Как мне сделать эту анонимную функцию Javascript ссылкой на правильную переменную? - PullRequest
2 голосов
/ 11 июля 2010

Пример:

var o = {};
for(var i = 0; i < 5; i++) {
  o[i] = function () {
      console.log(i);
  };
}

o[3]();

Когда я вызываю o3, он всегда отображает 5 на консоли, даже если я вызываю o0, o4 или любой из них. Это всегда будет отображать 5, потому что это последнее значение, которое я имел. Как мне сделать так, чтобы отображалось значение i при создании анонимной функции? Как в o3 должно отображаться 3 в консоли.

Ответы [ 2 ]

5 голосов
/ 11 июля 2010

Вы должны сделать:

var o = {};
for(var i = 0; i < 5; i++) {
  (function(i) { // <- self-executing anonymus function with a parameter i
    o[i] = function () {
        console.log(i); // <- i here will be the argument i, 
                        //    not the i from the loop
    };
  })(i); // <- pass i as an argument
}

o[3]();

Что происходит, когда вы создаете что-то, называемое closure , чтобы сохранить состояние i .

Закрытие означает, что внутренняя функция сохраняет ссылку на внешнюю функцию и, таким образом, получает доступ к ее переменным и параметрам (даже после внешняя функция вернулась).

Тривиальный пример закрытия:

function outer(arg) { 
  var variable = 5;
  arg = 2;
  function inner() {
    alert(variable);  // <- the inner function has access to the variables
    alert(arg);       //     and parameters of the outer function
  }
}

Самовыполняющаяся (самовыполняющаяся или немедленная) функция - это функция, которая вызывается сразу после ее объявления.

(function() {
  alert("executed immediately");
})();

Сочетание обоих и того факта, что только функции имеют scope в Javascript, приводит вас к упомянутой выше методике для создания scope с новой функцией, которая сохраняет состояние i , который в противном случае изменился бы внутренней функцией из-за замыкания .

1 голос
/ 11 июля 2010
o[i] = (function (i) {
    return function () { console.log(i); }
})(i);
...