@fleshik

Как работает замыкание в js?

function createCounter() { 
    let counter =0; 
   counter = counter - 10  
    const myFunction = function () { 
        counter = counter+1; 
        return counter 
    } 
    return myFunction 
} 
let z = createCounter() 
 
console.log(z()) 
createCounter() 
console.log(z())


Подскажите почему при последнем вызове console.log(z()) мы получаем (-8), а не (-9)
Первый вызов console.log(z()) нам дает let counter =0; далее (counter - 10 ) получаем (-10) далее
counter = (-10) + 1 =(-9); но ведь потом мы вызываем createCounter() и снова let counter =0; и при вызове console.log(z()) у нас let counter =0; почему мы тогда получаем (-8), а не (-9) где я допускаю ошибку
Подскажите почему так происходит и как работает данный код ?
Второй вопрос откуда берется counter при втором вызове console.log(z()) эта переменная берется с function createCounter() то есть перезаписанная let counter; или с функции myFunction (переменная counter = counter+1; )
  • Вопрос задан
  • 159 просмотров
Решения вопроса 1
MrDecoy
@MrDecoy Куратор тега JavaScript
Верставший фронтендер
function createCounter() { 
    let counter =0; 
   counter = counter - 10  
    const myFunction = function () { 
        counter = counter+1; 
        return counter 
    } 
    return myFunction 
} 
let z = createCounter() // Вернули в переменную z функцию "myFunction" у которой в замыкании есть counter.
// counter внутри на данный момент равен -10.

// Вызвали функцию и вывели результат в консоль.
// Так как внутри функции counter берётся из замыкания, то при вызове функции получаем
// -10 + 1
console.log(z()) // -9

// В данном примере - бесполезный ничего не делающий вызов.
// То есть создаётся ещё один НОВЫЙ счётчик, со своим замыканием, но он никуда не сохраняется.
createCounter() 

// Снова вызвали функцию и вывели результат в консоль.
// -9 + 1 
console.log(z()) //  -8


где я допускаю ошибку

Судя по всему Ваша ошибка в том, что Вы считаете, раз снова вызвали функцию createCounter - то это на что-то влияет. Но нет. Это отдельный новый вызов нового счётчика, который потом в данном примере нигде не используется.

Второй вопрос откуда берется counter при втором вызове console.log(z())

Да всё оттуда же. Из замыкания. Когда Вы в первый раз вызвали функцию createCounter и сохранили результат её работы в переменную z - Вы в переменную z поместили функцию myFunction, у которой есть своё собственное замыкание на counter.
При каждом вызове z() будет вызываться та созданная функция со своим замыканием и оперировать с counter из него.

При новом вызове createCounter возвращается НОВАЯ функция myFunction у которой своё независимое от предыдущих вызовов замыкание.
То есть createFunction это как фабрика, которая выпускает одинаковые изделия(счётчики от -10, в данном случае), но изделия не зависят друг от друга.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
Каждый вызов createCounter() создаёт и возвращает новую функцию. С которой в комплекте идёт свой новый «чемодан» замыкания, в котором лежит своя переменная counter.
Каждый раз отдельная-новая.

откуда берется counter при втором вызове console.log(z())

Из того же «чемодана» от первого вызова createCounter()
Ответ написан
Ваш ответ на вопрос

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

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