Почему замыкания лучше, чем глобальные переменные для сохранения переменных? - PullRequest
6 голосов
/ 27 декабря 2010

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

Ответы [ 6 ]

7 голосов
/ 27 декабря 2010

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

4 голосов
/ 27 декабря 2010

Два слова: условия гонки .

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

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

Можно повторно использовать состояние последнего экземпляра, который установил эту переменную (если у вас нет нескольких активных одновременно экземпляров).

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

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

Помещение переменных в глобальное пространство подвержено ошибкам и создает беспорядокntime view.Возможности JS в области видимости также делают его ненужным, поэтому никто этого не делает (за исключением вещей, которые там действительно принадлежат).

В качестве дополнительного комментария не упоминайте свой возраст и не хвастайтесь своим мастерством кодирования вбудущие вопросы.Это не имеет отношения к вопросу.

2 голосов
/ 27 декабря 2010

Ну, в JavaScript есть только одно глобальное пространство имен, поэтому было бы довольно сложно использовать разные Frameworks / Toolkits на одной странице, потому что рано или поздно имена переменных начнут конфликтовать. *

Также замыкания предоставляют способ эмулировать частные переменные:

function Counter(start) {
   var count = start;
   return {
       increment: function() {
           count++;
       },

       get: function() {
           return count; // only gives you the value, but no write access
       }
   }
}

Но это довольно «глупый» пример, замыкания особенно полезны, когда дело доходит до всех видов обратных вызовов, вы не хотите управлять глобальными массивами, которые содержат данные для каждого обратного вызова, это намного проще и чище закрытие.

Для экстремального использования замыканий взгляните на реализацию класса для JavaScript. (Отказ от ответственности, код был написан мной.)

Здесь proto отслеживает необработанные свойства каждого класса, но он все еще доступен для extend, который затем может добавить эти свойства в другие классы, когда они наследуются от другого.

1 голос
/ 17 августа 2014

Выходя из дома, рекомендуется отдать ключ соседу, чтобы ваш супруг (а) мог забрать его в случае, если он / она приходит домой рано, но НЕ БУДЕТ бросать его в дорогу.

1 голос
/ 27 декабря 2010

Все остальные уже упоминали загрязнение имен golbal и global is evil , даже OP:

Или это загромождает глобальный охват ...

но есть еще одна причина.

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

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

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


И что вы знаете, так же, как я прокручивал вниз после того, как отправил этот ответ, я нашел вопрос, иллюстрирующий проблему с глобальными переменными: Как вы создаете несколько таймеров на одной странице, которые работают независимо - javascript?.Хотя для этой конкретной проблемы вам не нужно замыкание, просто старые локальные переменные.

1 голос
/ 27 декабря 2010

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

js> makeadd = function(num) { return function(val) { return num+val } }
function (num) {
    return function (val) {return num + val;};
}
js> add3 = makeadd(3)
function (val) {
    return num + val;
}
js> add4 = makeadd(4)
function (val) {
    return num + val;
}
js> add3(add4(2))
9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...