shake_shake1
@shake_shake1
HTML-программист, 1С-разработчик, чиню утюги.

Как понять замыкания, а в частности, присвоения вида fn = function()?

Я никак не могу понять объявление функции типа var counter = makeCounter();
После этого вызов counter() идентичен вызову makeCounter()()?

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

function createCounter() {
   var numberOfCalls = 0;
   return function() {
      return ++numberOfCalls;
   }
}
createCounter()();
createCounter()();
alert(createCounter()()); // выводит 1

var fn = createCounter();

fn();
fn();
alert(fn()) // выводит 3
  • Вопрос задан
  • 315 просмотров
Решения вопроса 3
Ni55aN
@Ni55aN
Почему первый не работает? Там все как надо:
при вызовеcreateCounter()инициализируется numberOfCallsсо значением 0 и возвращается функция, которая "видит" эту переменную. В дальнейшем вызове этой анонимной функции она все так же будет видеть numberOfCalls.

В первом случае при вызове createCounter заново каждый раз создается переменная с 0
Во втором случае при вызове fn()одна и та же анонимная функция использует одну и ту же переменную numberOfCalls
Ответ написан
PretorDH
@PretorDH
HTML5, CSS3, PHP, JS - люблю в чистом виде.
Все просто. В замыкании и не замыкании нет разницы для интерпретатора - это не исключительная ситуация.
Нужно понять: замыкание это алгоритм, а не конструкция как например цикл или функция!!!

Функция createCounter() - возвращает анонимную функцию.
В анонимной функции используется переменная createCounter.

При просто вызове createCounter()(); :
createCounter() - инициализирует переменную (три раза) и возвратит анонимную функцию.
И три раза происходит вызов анонимной функции - вторые ().
После каждого из трех вызовов переменная numberOfCalls созданная при вызове createCounter уже не нужна.
Анонимная функция больше не будет использована в этом контексте.
В итоге функция и замкнутая переменная три раза попадают в уборщик мусора.

При Сохранении анонимной функции в переменную:
Во-первых: numberOfCalls будет инициализирована только один раз, при записи fn = createCounter().
Где контекст анонимной функции записывается в переменную fn.
Во-вторых: так как контекст вызова сохранен, то замкнутая переменная и анонимная функция останутся лежать в нем.
В-третьих: при каждом вызове анонимной функции в сохраненном контексте переменная будет увеличиваться так как старое значение не инициализировано и не выброшено.

var fn = createCounter();

fn();
fn();
alert(fn())  // =3
fn = createCounter();
fn();
alert(fn())  // =2
Ответ написан
yarkov
@yarkov Куратор тега JavaScript
Помог ответ? Отметь решением.
Вызывая createCounter()() вы каждый раз заново создаете такой участок:
var numberOfCalls = 0;
   return function() {
      return ++numberOfCalls;
   }

Вызывая

var fn = createCounter()
fn()

Вы создаете этот участок один раз и в fn теперь ссылка на этот код. То есть переменная numberOfCalls не обнуляется каждый раз.
- - -
Объяснил как смог )))
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы