Это распространенная ошибка (также известная как проблема печально известного цикла Javascript ), вызванная неправильным пониманием замыканий. Вот очень простой пример:
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs[i] = function() { return i; };
}
> funcs[0]();
5
> funcs[1]();
5
Главное, что здесь нужно понять, это то, что замыкание закрывает (или запоминает, или «захватывает») ссылки на нелокальные (или свободные) переменные. Теперь акцент делается на ссылок , т. Е. Замыкание не захватывает значения свободных переменных, а захватывает ссылки на их имена.
Если замыкание запомнит значения свободных переменных, то у нас будет (ошибочно) ожидаемое поведение funcs[0]()
, возвращающее 0
и т. Д. Если замыкание запомнит значения свободных переменных, то мы можем сказать, что замыкание делает «снимок» этих значений в данный конкретный момент времени.
Но это не то, что делает закрытие.
Закрытия запоминают ссылки на свободные переменные, а не их значения.
В этом примере funcs[i]
запоминает ссылку на i
. При вызове он ищет значение глобальной переменной i
, и это значение в настоящее время равно 5.
Что действительно помогло мне понять это, так это эта лекция стр. 12-15, из которой я использовал некоторые выдержки вместе с определением Википедии .