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

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

Я думаю о функции, что, когда питается два аргумента (function globalVariables(Variable,Value)) взгляды, если Переменная существует в локальном массиве и если она действительно устанавливает, это - значение к Value, еще, Variable и Value добавляются. Если функция вызвана без аргументов (function globalVariables()) это возвращает массив. Возможно, если функция запущена со всего одним аргументом (function globalVariables(Variable)) это возвращает значение Variable в массиве.

Что Вы думаете? Я хотел бы услышать Ваши альтернативные решения и аргументы в пользу использования глобальных переменных.

Как Вы использовали бы globalVariables();

function append(){
    globalVariables("variable1","value1"); //globalVariables() would append variable1 to it's local array.
};

function retrieve(){
    var localVariable1 = globalVariables("variable1"); //globalVariables() would return "value1".
};

function retrieveAll(){
    var localVariable1 = globalVariables(); //globalVariables() would return the globalVariable()'s entire, local [persistently stored between calls] array.
};

function set(){
    globalVariables("variable1","value2"); //globalVariables() would set variable1 to "value2".
};

Действительно ли это - Шаблон "одиночка" BTW?

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

Спасибо, я ценю всю Вашу справку!

71
задан Jonathon Oates 10 April 2010 в 13:17
поделиться

5 ответов

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

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

var FOO = (function() {
    var my_var = 10; //shared variable available only inside your module

    function bar() { // this function not available outside your module
        alert(my_var); // this function can access my_var
    }

    return {
        a_func: function() {
            alert(my_var); // this function can access my_var
        },
        b_func: function() {
            alert(my_var); // this function can also access my_var
        }
    };

})();

Теперь, чтобы использовать функции в вашем модуле в другом месте, используйте FOO.a_func () . Таким способом разрешить конфликты глобальных пространств имен вам нужно только изменить имя FOO .

132
ответ дан 24 November 2019 в 12:52
поделиться

Вы действительно не хотите этого делать.
Относительно того, почему, см., Например, верхний пост здесь: Какой самый ЗЛОЙ код вы когда-либо видели в производственной корпоративной среде?

Кстати, всегда можно выполнить «глобальный» код, не захламляя место глобальными переменными:

(function () {
    var notaglobal = 1;
    alert(notaglobal);
})();
//notaglobal is not defined in this scope        
3
ответ дан 24 November 2019 в 12:52
поделиться

Семантика, мой мальчик. Семантика.

Начните с одного глобального: myApp = {}; В нем должно быть все. Единственным исключением будет ваша библиотека AJAX (есть несколько крайних исключений, например, работа с обратными вызовами JSONP).

В myApp должно быть очень мало свойств. Вы захотите хранить свойства своего приложения в контейнерах, таких как config или settings.

myApp = {
    config:{
        prop:1
    },
    settings:{
        prop:2
    },
    widgets:{
        List: function(props){},
        Item: function(props){}
    }
}

Тогда у вас может быть больше свойств в нижних модулях, компонентах, синглетонах и конструкторах классов (виджетах).

Эта установка дает вам дополнительное преимущество, заключающееся в возможности доступа к любому свойству из любого другого места, поскольку вы можете получить его с помощью myApp global. Однако вы должны использовать "this", когда это возможно, потому что поиск выполняется быстрее. И просто установите свойство напрямую, не беспокойтесь о псевдогеттерах / сеттерах. Если вам действительно нужен геттер / сеттер, запрограммируйте его для этого конкретного использования.

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

И не умничай с частными переменными. Они тоже плохие: http://clubajax.org/javascript-private-variables-are-evil/

40
ответ дан 24 November 2019 в 12:52
поделиться

Глобальное состояние вызывает проблемы в нескольких областях. Одна из них - повторное использование кода. Когда вы обращаетесь к некоторому глобальному состоянию, это означает, что компонент должен знать о своем окружении (что-то вне себя). Вы должны избегать этого как можно больше, потому что это делает компонент непредсказуемым.

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

Кроме того, когда вы обращаетесь к глобальной области видимости или изменяете ее, вы рискуете повлиять на другие объекты. Вот почему такие библиотеки, как jquery, используют только одно имя в глобальной области видимости (минимально возможное). Это уменьшает вероятность конфликта с другими библиотеками. Другими словами, глобальная область видимости находится вне вашего контроля, поэтому она опасна.

9
ответ дан 24 November 2019 в 12:52
поделиться

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

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

2
ответ дан 24 November 2019 в 12:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: