Здравствуйте! Изучаю замыкания и натолкнулся на следующий момент. Имеется пример!
function outer (){
let counter = 0;
function incrementCounter (){
counter ++;
}
return incrementCounter;
}
let myNewFunction = outer();
myNewFunction();
myNewFunction();
var anotherFunction = outer(); // myNewFunction = incrementCounter
anotherFunction();
anotherFunction();
Результат вызова myNewFunction() равен 1. Следующий 2…
Не совсем понятно, почему результат функции anotherFunction() имеет другую ссылку на внешний объект.
Вот как я это понимаю.
При определении функции incrementCounter(как и любой другой, в том числе и внешней, глобальной функции), javascript интерпретатор создаёт специальный внутренний объект [[scope]], который содержит все переменные этой функции, в том числе и ссылку на окружение, в котором создавалась данная функция(кстати, и здесь у меня сейчас появился вопрос… что такое scope? Ведь у нас есть локальная память функции, в которой сохраняются переменные. В Scope храниться только ссылка на внешнее окружение и на переменную counter, в нашем случае…??? То есть, при определении функции, создаётся локальная память и Scope?) … Далее, сохраняя функцию outer в переменную myNewFunction, мы сохраняем в том числе и scope, то есть ссылку на внешнее окружение. Но почему тогда, одна и та же ссылка не сохраняется в разные переменные? Мы не можем сохранить значение counter, которое после двух вызовов myNewFunction равняется 2 и продолжить увеличивать в 3 и 4. Очень прошу объяснить этот момент! И поправьте пожалуйста меня там, где я ошибся!
Представь что при вызовеouter код выполняется последовательно, выражение за выражением. Выходит создается переменная counter, создается функция incrementCounter. И созданный incrementCounter возвращается из функции. По механике работы интерпретатора - где и как бы не вызывалась incrementCounter, ей всегда доступны переменные из того места где она была создана. Это место называют scope.
А myNewFunction и anotherFunction разные потому что это 2 разных объекта которые создались в двух вызовах outer.
Я не думаю что scope работает так же как и свойства js. Это внутреннее свойство интерпретатора и может содержать в себе что угодно, хоть айдишник на часть структуры что хранит в себе ссылки на значения из подобласти видимости.
Так можно сказать.
Скорее функция из myNewFunction видит тот скоуп в котором была создана.
При каждом вызове outer создается новый скоуп и новая incrementCounter, и новый counter.
Вызов outer так же создал область видимости в которой создалась функция incrementCounter и coutner. myNewFunction ссылается на функцию что создана и возвращена из outer. Вызов myNewFunction изенит значение переменной counter в той области видмости в которой myNewFunction была объявлена. В итоге значение counter будет 2. Это можно проверить, добавив console.log после инкремента в вызове incrementCounter
Тут вызов outer создал новый скоуп, новый counter и новую incrementCounter.Ссылка на incrementCounter записана в anotherFunction. А дальше 1 в 1 как в сообщении выше.
Всё, я понял! Здесь:
let myNewFunction = outer();
мы вызываем outer и сохраняем функцию incrementCounter в myNewFunction и повторно вызываем внутреннюю функцию. А ниже:
var anotherFunction = outer();
мы вызываем внешнюю функцию с новой переменной counter, которая равна 0