Вопрос закрытия JavaScript: почему второй вызов externalFn создает новый экземпляр outerVar? - PullRequest
1 голос
/ 15 июля 2011

У меня вопрос по JavaScript.Позвольте мне процитировать цитату из книги «Обучение jQuery», стр. 389-390.Вопрос касается Closures.

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

Что такое в JavaScript, что могло бы сделать это так? Что мне нужно знать о JavaScript, чтобы я мог сделать это для себя?

Остальныеписьмо - это цитата из книги.

function outerFn() {
  var outerVar = 0;
  function innerFn() {
    outerVar++;
    $('#example-7').print('outerVar = ' + outerVar);
  }
  return innerFn;
}
var fnRef = outerFn();
fnRef();
fnRef();
var fnRef2 = outerFn();
fnRef2();
fnRef2();

Теперь наши вызовы функций имеют более интересное поведение: externalVar = 1 outerVar = 2 outerVar = 1 outerVar = 2 Мы получаем смесь двух предыдущих эффектов.Вызывает innerFn () через каждый ссылочный инкремент externalVar независимо. Обратите внимание, что второй вызов externalFn () не сбрасывает значение externalVar, а скорее создает новый экземпляр outerVar, связанный с областью действия второго вызова функции.это означает, что после вышеуказанных вызовов другой вызов fnRef () выведет значение 3 и последующий вызов fnRef2 () также выведет 3. Два счетчика полностью разделены.

Ответы [ 4 ]

2 голосов
/ 15 июля 2011

Ну, вот и вся идея замыканий . Как указано в первом абзаце вышеупомянутой вики-ссылки:

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

Такое поведение не является особенностью javascript - так происходит на всех языках, которые поддерживают замыкания

0 голосов
/ 15 июля 2011

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

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

0 голосов
/ 15 июля 2011

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

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

0 голосов
/ 15 июля 2011

Возможно, вы слишком обдумываете это.

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

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