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

Я продвигаюсь вперед в понимании замыканий, но я не понимаю, как следующий пример даже создает замыкания. Я процитирую отрывок из раздела «Изучение jQuery», стр. 392. Что говорит автор об этом примере.

Автор говорит, что, поскольку "readyVar сохраняется между вызовами функции", мы видим, что происходит замыкание. Но для меня readyVar сохраняется между вызовами innerFn просто потому, что анонимная функция еще не завершила выполнение. Как только анонимная функция завершит свою работу, не будет никаких ссылок на readyVar, и она будет собирать мусор. Так где же закрытие? У меня сложилось впечатление, что замыкание включает переменную, на которую можно ссылаться в области за пределами той области, в которой переменная была определена. Но я не вижу этого здесь.

Автор говорит, что всякий раз, когда внутренняя функция ссылается на значение, определенное во внешней функции, создается замыкание? Это не может быть тем, что он говорит, не так ли?

Остальная часть этого сообщения - цитата из вышеупомянутой книги.

$(document).ready(function() {
  var readyVar = 0;
  function innerFn() {
    readyVar++;
    $('#example-9').print('readyVar = ' + readyVar);
  }
  innerFn();
  innerFn();
});

Это похоже на многие из наших предыдущих примеров, за исключением того, что в этом случае внешней функцией является обратный вызов, передаваемый в $ (document) .ready (). Поскольку innerFn () определен внутри него и ссылается на readyVar, который находится в области действия функции обратного вызова, innerFn () и его окружение создают замыкание. Это можно увидеть, заметив, что значение readyVar сохраняется между вызовами функции: readyVar = 1 readyVar = 2

1 Ответ

1 голос
/ 16 июля 2011

В течение функции $(document).ready все ее локальные переменные активны и содержат свои значения, и любой код в этой функции или любых встроенных функциях может ссылаться на них.Хотя это можно описать как замыкание функции, это больше просто то, как локальные переменные работают в функции.

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

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

Теперь, если вы изменили его, добавив обработчик кликов, подобный этому, теперь у вас есть постоянная ссылка на функцию внутри функции $(document).ready с функцией обработчика кликов.Поскольку он продолжается, даже после завершения цикла $(document).ready он не будет собирать мусор и будет работать как закрытие функции.

$(document).ready(function() {
  var readyVar = 0;
  function innerFn() {
    readyVar++;
    $('#example-9').print('readyVar = ' + readyVar);
  }
  innerFn();
  innerFn();
  $("#content").click(function(){  // external reference to within this function
      alert(readyVar);
  });
});

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

Возможно, вы найдете это полезным: http://blog.morrisjohns.com/javascript_closures_for_dummies.html

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