Как работают счетчики? [дубликат]

232
14 мая 2018, 06:50

На данный вопрос уже ответили:

  • Как работают замыкания в JavaScript 6 ответов

При объяснении как работает [[Scope]] зачачстую встречается такой пример:

function makeCounter() {
      var currentCount = 1;
      return function() {
        return currentCount++;
      };
    }
    var counter = makeCounter();
    alert( counter() ); // 1
    alert( counter() ); // 2
    alert( counter() );

Почему такой счетчик работает - для меня совершенно непонятно.

Каким образом число сохраняеется если каждый раз функция присваевает переменной еденицу?

Answer 1

Чтобы было легче понять пример, рекомендую отвлечься от замыканий:

var currentCount = 1; 
 
var counter = function() { 
  return currentCount++; 
}; 
 
console.log(counter(), counter(), counter());

Пример из вопроса отличается только тем, что этот код завёрнут в функцию, которая позволяет иметь несколько счётчиков со своими внутренними переменными в каждой.

function getCounter() { 
  // тот же код 
  var currentCount = 1; 
 
  var counter = function() { 
    return currentCount++; 
  }; 
 
  // вернём counter 
  return counter; 
} 
 
 
var c1 = getCounter(); // вызываем всего 1 раз, значит и единицу присвоим один раз 
// в переменной c1 в данный момент функция из локальной переменной counter 
console.log('c1 =', c1); 
 
// и мы можем вызывать её, как и в примере без функции выше 
console.log('c1()', c1(), c1()); 
 
// Также, всегда можно получить новый счётчик: 
var c2 = getCounter(); 
console.log('c2()', c2(), c2(), c2()); 
 
   

Answer 2

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

Это вкратце. Вроде ничего не напутал. Более подробно можно почитать например тут – https://learn.javascript.ru/functions-closures

P.S. makeCounter() не вызывает анонимную функцию, а возвращает ее и она у вас находится в переменной counter, которую вы вызываете как функцию.

P.P.S. На эту тему есть кстати много ответов уже, и вот один из них. Спасибо @MedvedevDev – Как работают замыкания в JavaScript

P.P.P.S Как работают функциональные выражения можно почитать например тут – https://learn.javascript.ru/function-declaration-expression

READ ALSO
JavaScript this.getAttribute is not a function [дубликат]

JavaScript this.getAttribute is not a function [дубликат]

На данный вопрос уже ответили:

254
crypto-worker.js Cannot read property 'setKey' of null

crypto-worker.js Cannot read property 'setKey' of null

Использую VueЧтобы заново не генерировать ключи при каждом обращении, достал ключ из локального хранилища, обозначил константой и пробую...

273
Как правильно написать async function javascript

Как правильно написать async function javascript

Решаю задание и вот возникла проблема з написанием функцииВсе методы прописал, а вот как задейсвовать их не знаю

221