Вопрос

Может ли кто-нибудь объяснить мне (ясно и кратко), почему этот код работает именно так?Я имею опыт строго типизированной работы с Java (6 и 7), где замыкания не существуют и не работают так, как в JavaScript.Я думаю, что концепции, связанные с этим вопросом, следующие:замыкания и цепочка областей видимости.

Вот пример:

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = function() { console.log(i); }
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); });

В приведенном выше примере регистрируется 9 (10 раз), но мои ожидания и моя собственная интуиция предполагали, что будет зарегистрировано 0–9.

Почему это работает так, как в Javascript?Замыкания — это очень мощное средство, но я пытаюсь усвоить эту концепцию раз и навсегда!Слегка измененный пример дает правильный результат, но почему?

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = (function(index) { console.log(index); })(i);
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); }); 

Замыкания не являются уникальными для Javascript, но я хочу понять, почему они эффективны в контексте того, когда JavaScript фактически написан для взаимодействия с браузером/домом.

Есть ли у кого-нибудь хорошие практические примеры того, как мы можем применять технику закрытия при взаимодействии с браузером/домом?

Спасибо.

Это было полезно?

Решение

В приведенных вами примерах это очень просто.

В вашем первом примере есть только одна переменная i и все ссылается на это единственное значение.Так..он печатает номер 9 десять раз.Каждая функция захватывает общий значение i это меняется.

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

Итак, вы получаете 0 через 9 потому что есть десять функций, каждая из которых имеет приватный index переменная и каждая из них index переменные получают снимок i как оно существовало в то время.

Эта более длинная форма закрытия может помочь:

function myFactory(index) {
  return function() {
    console.log(index);
  }
}

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = myFactory(i);
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); }); 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top