Клостеры JavaScript

JavaScript переменные относятся клокальныеилиГлобальныеобласть видимости.

Глобальные переменные могут быть получены черезКонтурРеализуют локальные (частные).

Глобальные переменные

Функция может обращаться к функцииВнутренниеОпределенные все переменные, например:

Пример

function myFunction() {
    var a = 4;
    return a * a;
} 

Попробуйте сами

Но функция также может обращаться к функциямВнешниеОпределенные переменные, например:

Пример

var a = 4;
function myFunction() {
    return a * a;
} 

Попробуйте сами

В последнем примереa являютсяГлобальныеПеременные.

В веб-странице глобальные переменные都属于 объекту window.

Глобальные переменные могут быть использованы и изменены всеми скриптами на странице (и в окне).

В первом примереa являютсяЛокальныеПеременные.

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

имеющие одинаковые имена глобальные и локальные переменные — это разные переменные. Изменение одной не изменяет другую.

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

Жизненный цикл переменных

Глобальные переменные живут так же долго, как ваше приложение (окно, веб-страница).

Локальные переменные живут недолго. Они создаются при вызове функции и удаляются после завершения функции.

Трудности счетчика

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

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

Пример

// Инициализация счетчика
var counter = 0;
// Функция для увеличения счетчика
function add() {
  counter += 1;
}
// Вызов add() три раза
add();
add();
add();
// В этот момент счетчик должен быть 3

Попробуйте сами

Указанное решение имеет одну проблему: любое код на странице может изменить счетчик, не вызывая add().

Для функции add() счетчик должен быть локальным, чтобы предотвратить изменения его другими кодами:

Пример

// Инициализация счетчика
var counter = 0;
// Функция для увеличения счетчика
function add() {
  var counter = 0; 
  counter += 1;
}
// Вызов add() три раза
add();
add();
add();
// В этот момент счетчик должен быть 3. Но он 0.

Попробуйте сами

Оно не нужно, потому что мы показываем глобальный счетчик, а не локальный счетчик.

Позволяя функции возвращать себя, мы можем удалить глобальный счетчик и обращаться к локальному счетчику:

Пример

// Функция для увеличения счетчика
function add() {
  var counter = 0; 
  counter += 1;
  return counter;
}
// Вызов add() три раза
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 метода.

Нам нужны контуры (closure).

Клостеры JavaScript

Помните ли вы функции самоисполнения? Что они делают?

Пример

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
add();
add();
add();
// Счетчик в настоящее время равен 3 

Попробуйте сами

Примеры объяснения

Переменная add Ассигнование является значением, возвращаемым самоисполнением функции.

Эта функция вызывается один раз. Она устанавливает счетчик в ноль (0) и возвращает выражение функции.

Таким образом, add становится функцией. Самый «запоминающийся» момент - это то, что она может получить доступ к счетчику в родительском контексте.

Это называется Контур. Это позволяет функции иметьПриватныйЭто делает возможным

Контур защищает счетчик, и его можно изменить только с помощью функции add.

Контур - это функция, которая имеет доступ к родительскому контексту, даже после того, как родительская функция завершена.