JavaScript Закрытие функции
Переменные JavaScript могут принадлежать к локальной или глобальной области.
Глобальные переменные можно сделать локальными (частными) с помощью замыканий.
Глобальные переменные
function может получить доступ ко всем переменным, определенным внутри функции, например:
Но function также может обращаться к переменным, определенным вне функции, например:
В последнем примере a - это глобальная переменная.
На веб-странице глобальные переменные принадлежат объекту window.
Глобальные переменные могут использоваться (и изменяться) всеми скриптами на странице (и в window).
В первом примере a - это локальная переменная.
Локальную переменную можно использовать только внутри функции, в которой она определена. Она скрыта от других функций и другого скриптового кода.
Глобальные и локальные переменные с одинаковыми именами - это разные переменные. Изменение одной не изменяет другую.
Переменные, созданные без ключевого слова объявления (var,
let, или const),
всегда являются глобальными, даже если они созданы внутри функции.
Продолжительность жизни переменной
Глобальные переменные существуют до тех пор, пока страница не будет отброшена, например, когда вы переходите на другую страницу или закрываете окно.
У локальных переменных короткий срок жизни. Они создаются при вызове функции и удаляются по завершении функции.
Встречная дилемма
Предположим, вы хотите использовать переменную для подсчета чего-либо и хотите, чтобы этот счетчик был доступен для всех функций.
Вы можете использовать глобальную переменную и function для увеличения счетчика:
Пример
// Запуск счетчика
var counter = 0;
// Функция увеличения счетчика
function add() {
counter += 1;
}
// Вызов add() 3 раза
add();
add();
add();
// Счетчик теперь должен быть 3
Попробуйте сами »
Существует проблема с решением, приведенным выше: любой код на странице может изменить счетчик без вызова add().
Счетчик должен быть локальным для add() функции, чтобы другой код не мог его изменить:
Пример
// Запуск счетчика
var counter = 0;
// Функция увеличения счетчика
function add() {
var counter = 0;
counter += 1;
}
// Вызов add() 3 раза
add();
add();
add();
// Счетчик теперь должен быть 3. Но он равен 0
Попробуйте сами »
Это не сработало, потому что мы отображаем глобальный счетчик вместо локального.
Мы можем удалить глобальный счетчик и получить доступ к локальному счетчику, позволив функции вернуть его:
Пример
// Функция увеличения счетчика
function add() {
var counter = 0;
counter += 1;
return counter;
}
// Вызов add() 3 раза
add();
add();
add();
// Теперь счетчик должен быть 3. Но он равен 1.
Попробуйте сами »
Это не сработало, потому что мы сбрасывали локальный счетчик каждый раз, когда вызываем функцию.
Внутренняя функция JavaScript может решить эту проблему.
Вложенные функции JavaScript
Все функции имеют доступ к глобальной области видимости.
Фактически, в JavaScript все функции имеют доступ к области, расположенной "над ними".
JavaScript поддерживает вложенные функции. Вложенные функции имеют доступ к области "над ними".
В этом примере внутренняя функция plus()
имеет доступ к counter переменной в родительской функции:
Пример
function add() {
var counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
Попробуйте сами »
Это могло бы решить встречную дилемму, если бы мы могли добраться до plus() функции извне.
Нам также нужно найти способ выполнить counter = 0 только один раз.
Нам нужно закрытие.
Замыкания JavaScript
Помните самозапускающиеся функции? Что они делают?
Пример
var add = (function () {
var counter = 0;
return function () {counter += 1; return counter}
})();
add();
add();
add();
// счетчик теперь 3
Попробуйте сами »
Объяснение примера
Переменная add присваивается возвращаемому значению самозапускающейся функции.
Самозапускающаяся функция запускается только один раз. Он устанавливает счетчик на ноль (0) и возвращает выражение функции.
Таким образом, add становится функцией. "Замечательно" то, что он может получить доступ к счетчику в родительской области.
Это называется закрытием JavaScript. Это позволяет функции иметь "частные" переменные.
Счетчик защищен областью действия анонимной функции и может быть изменен только с помощью функции добавления.
Замыкание - это функция, имеющая доступ к родительской области, даже после закрытия родительской функции.
