Какие правила регулируют копирование переменных в замыканиях Javascript? - PullRequest
1 голос
/ 21 марта 2010

Я просто хотел бы проверить мое понимание копирования переменных в Javascript. Насколько я понимаю, переменные передаются / присваиваются по ссылке, если вы явно не скажете им создать копию с оператором new. Но я немного не уверен, когда дело доходит до использования замыканий. Скажем, у меня есть следующий код:

var myArray = [1, 5, 10, 15, 20];
var fnlist = [];
for (var i in myArray) {
    var data = myArray[i];
    fnlist.push(function() {
        var x = data;
        console.log(x);
    });
}
fnlist[2](); // returns 20

Я понимаю, что это потому, что fnlist[2] ищет значение data только в том месте, где оно вызывается. Поэтому я попробовал альтернативный вариант:

var myArray = [1, 5, 10, 15, 20];
var fnlist = [];
for (var i in myArray) {
    var data = myArray[i];
    fnlist.push(function() {
        var x = data;
        return function() {
            console.log(x);         
        }
    }());
}
fnlist[2](); // returns 10

Так что теперь он возвращает «правильное» значение. Правильно ли я сказал, что это работает, потому что функция разрешает все ссылки на переменные в их «постоянные» значения при вызове? Или есть лучший способ объяснить это?

Будем также благодарны за любые объяснения / ссылки на объяснения, касающиеся этой ссылки / копирования. Спасибо!

1 Ответ

1 голос
/ 21 марта 2010

Переменные замыкания привязываются («сохраняются» в замыкании) в тот момент, когда заканчивается его область действия, то есть когда вы покидаете функцию, в которой определено замыкание:

function make_closure() {
   var x = 10;
   var closure = function() { alert(x) }
   x = 20
   return closure;
}

func = make_closure()
func() // what do you think?

Решение, которое вы нашли, совершенно правильно - вы вводите еще одну область действия и принудительное закрытие для связывания переменных в этой «внутренней» области.

См. здесь для подробностей и объяснений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...