Доступ к переменным из других функций без использования глобальных переменных

StackOverflow https://stackoverflow.com/questions/407048

  •  03-07-2019
  •  | 
  •  

Вопрос

Я слышал из разных мест, что глобальные переменные по своей сути неприятны и порочны, но при выполнении некоторых не объектно-ориентированных Javascript я не вижу, как их избежать.Допустим, у меня есть функция, которая генерирует число с использованием сложного алгоритма, использующего случайные числа и прочее, но мне нужно продолжать использовать это конкретное число в какой-то другой функции, которая является обратным вызовом или чем-то еще и поэтому не может быть частью той же функции.

Если первоначально сгенерированный номер является локальной переменной, он не будет доступен оттуда.Если бы функции были объектными методами, я мог бы сделать число свойством, но это не так, и изменение всей структуры программы для этого кажется несколько чрезмерно сложным.Действительно ли глобальная переменная так плоха?

Это было полезно?

Решение

Чтобы сделать переменную, вычисляемую в функции A, видимой в функции B, у вас есть три варианта:

  • сделайте это глобальным,
  • сделайте это свойством объекта, или
  • передавайте его в качестве параметра при вызове B из A.

Если ваша программа довольно маленькая, то глобальные переменные не так уж и плохи.В противном случае я бы рассмотрел возможность использования третьего метода:

function A()
{
    var rand_num = calculate_random_number();
    B(rand_num);
}

function B(r)
{
    use_rand_num(r);
}

Другие советы

Я думаю, что вашим лучшим выбором здесь может быть определение одинокий переменная с глобальной областью действия и сброс ваших переменных туда:

var MyApp = {}; // Globally scoped object

function foo(){
    MyApp.color = 'green';
}

function bar(){
    alert(MyApp.color); // Alerts 'green'
} 

Никто не должен кричать на вас за то, что вы делаете что-то подобное вышеописанному.

Рассмотрите возможность использования пространств имен:

(function() {
    var local_var = 'foo';
    global_var = 'bar'; // this.global_var and window.global_var also work

    function local_function() {}
    global_function = function() {};
})();

И то , и другое local_function и global_function иметь доступ ко всем локальным и глобальным переменным.

Редактировать:Еще одна распространенная закономерность:

var ns = (function() {
    // local stuff
    function foo() {}
    function bar() {}
    function baz() {} // this one stays invisible

    // stuff visible in namespace object
    return {
        foo : foo,
        bar : bar
    };
})();

Тот Самый returnдоступ к редактируемым свойствам теперь можно получить через объект пространства имен, например ns.foo, сохраняя при этом доступ к локальным определениям.

То, что вы ищете, технически известно как приготовление карри.

function getMyCallback(randomValue)
{
    return function(otherParam)
    {
        return randomValue * otherParam //or whatever it is you are doing.
    }

}

var myCallback = getMyCallBack(getRand())

alert(myCallBack(1));
alert(myCallBack(2));

Приведенная выше функция не является в точности каррированной, но она обеспечивает сохранение существующего значения без добавления переменных в глобальное пространство имен или требования для него какого-либо другого репозитория объектов.

Если другой функции необходимо использовать переменную, вы передаете ее функции в качестве аргумента.

Кроме того, глобальные переменные по своей сути не являются неприятными и злыми.Пока они используются должным образом, с ними нет никаких проблем.

Если есть шанс, что вы будете повторно использовать этот код, то я бы, вероятно, приложил усилия, чтобы использовать объектно-ориентированную перспективу.Использование глобального пространства имен может быть опасным - вы рискуете столкнуться с труднодоступными ошибками из-за имен переменных, которые используются повторно.Обычно я начинаю с использования объектно-ориентированного подхода для чего-то большего, чем простой обратный вызов, так что мне не нужно ничего переписывать.Я думаю, что каждый раз, когда у вас есть группа связанных функций в javascript, это кандидат на объектно-ориентированный подход.

Другой подход - это тот, который я почерпнул из сообщения Дугласа Крокфорда на форуме(http://bytes.com/topic/javascript/answers/512361-array-objects).Вот оно...

Дуглас Крокфорд писал:

Июль 15 '06

"Если вы хотите извлекать объекты по идентификатору, то вам следует использовать object, а не array.Поскольку функции также являются объектами, вы могли бы хранить элементы в самой функции ."

function objFacility(id, name, adr, city, state, zip) {

    return objFacility[id] = {

        id: id,
        name: name,
        adr: adr,
        city: city,
        state: state,
        zip: zip

    }
}

objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);

"Объект может быть получен с помощью"

objFacility.wlevine

Доступ к свойствам объектов теперь доступен из любой другой функции.

Я нашел это чрезвычайно полезным по отношению к первоначальному вопросу:

Верните значение, которое вы хотите использовать в functionOne, затем вызовите functionOne внутри FunctionTwo, затем поместите результат в новый var и ссылайтесь на этот новый var внутри FunctionTwo.Это должно позволить вам использовать переменную, объявленную в functionOne, внутри FunctionTwo.

function functionOne() {
  var variableThree = 3;
  return variableThree;
}

function functionTwo() {
  var variableOne = 1;
  var var3 = functionOne();

  var result = var3 - variableOne;

  console.log(variableOne);
  console.log(var3);
  console.log('functional result: ' + result);
}

functionTwo();

Я не знаю специфики вашей проблемы, но если функции нужно значение, то это может быть параметр, передаваемый через вызов.

Глобальные переменные считаются плохими, потому что состояние глобальных переменных и несколько модификаторов могут создавать трудный для понимания код и странные ошибки.Для многих актеров возня с чем-то может создать хаос.

Вы можете полностью контролировать выполнение функций javascript (и передавать переменные между ними), используя пользовательские события jQuery....Мне сказали, что это невозможно на всех этих форумах, но у меня есть кое-что работающее, что делает именно это (даже используя вызов ajax).

Вот ответ (ВАЖНЫЙ:это не проверенный ответ, а скорее мой ответ "Эмиль"):

Как получить переменную, возвращаемую несколькими функциями - Javascript / jQuery

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top