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

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

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

Ответы [ 10 ]

71 голосов
/ 02 января 2009

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

var MyApp = {}; // Globally scoped object

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

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

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

51 голосов
/ 02 января 2009

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

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

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

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

function B(r)
{
    use_rand_num(r);
}
14 голосов
/ 02 января 2009

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

(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 ed теперь могут быть доступны через объект пространства имен, например, ns.foo, сохраняя при этом доступ к локальным определениям.

7 голосов
/ 02 января 2009

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

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));

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

4 голосов
/ 02 января 2009

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

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

2 голосов
/ 12 июня 2014

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

Верните значение, которое вы хотите использовать в 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();
2 голосов
/ 23 февраля 2013

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

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

15 июля 2006 г.

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

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

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

2 голосов
/ 02 января 2009

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

1 голос
/ 22 августа 2010

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

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

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

1 голос
/ 02 января 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...