2015-05-22 1 views
0
a = []; 
for (var i = 0; i < 3; i++) { 
    a.push(function() { 
     console.log(i); 
    }) 
} 

a[0]()  // I want 0, but I get 3 

Я пытаюсь написать простую часть кода, где у меня есть массив функций, так что когда я выполняю функцию в определенном индексе, значение индекса должно быть напечатано.Значение перезаписывается из-за доступа по ссылке

Однако в приведенном выше фрагменте показан тот же результат (3 в этом случае) для всех значений индекса. Я понимаю, что значение указывает по ссылке и поэтому указывает на последнее значение i. Может ли кто-нибудь указать, как это сделать правильно?

+0

Это дубликат [JavaScript закрытия внутри петли - простой практический пример] (http://stackoverflow.com/questions/750486/javascript- закрытие-внутри-петли-простой-практический пример) и [Javascript пресловутая проблема с циклом?] (http://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue). Пожалуйста, обратитесь к этому вопросу для подробных объяснений. –

+0

Большое спасибо @ Mr.Polywhirl –

ответ

2

Оберните его вокруг функции. Теперь каждый раз, когда цикл выполняется, функция-обертка имеет свое значение i.

a = []; 
for (var i = 0; i < 3; i++) { 
    (function(i){ 
     a.push(function() { 
      console.log(i); 
     }) 
    })(i); 
} 

a[0]() 
1

Вы можете добавить self executing function действовать как модуль. При этом область действия переменной i находится в этой функции.

a = []; 
 
for (var i = 0; i < 3; i++) { 
 
    (function(i){ 
 
     a.push(function() { 
 
      alert(i); 
 
     }) 
 
    })(i); 
 
} 
 

 
a[0]()

Примечание: В этом блоке (function(i){ ... })(i), i может иметь любое имя, не существует никакой связи между i из цикла и i из функции, т.е. (function(r){ ... })(r).

0

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

Проблема, с которой вы сталкиваетесь, заключается в том, что при вызове функции цикл уже был оценен, а значение i уже достигло максимального значения 3. Вам нужно поймать текущее значение i во время вычисления цикла.

var a = []; 
 

 
for (var i = 0; i < 3; i++) { 
 
    var fn = function() { 
 
    console.log(arguments.callee.i); 
 
    } 
 
    fn.i = i; // Pass as 'i' parameter to 'fn'. 
 
    a.push(fn); 
 
} 
 

 
a[0](); // The value 0 will be printed, rather than 3.

Существует более чем один способ кожи кошки. Приведенный выше код очень похож на:

var a = []; 
 

 
function fn(i) { 
 
    return function() { 
 
    console.log(i); 
 
    } 
 
} 
 

 
for (var i = 0; i < 3; i++) { 
 
    a.push(fn(i)); 
 
} 
 

 
a[0](); // The value 0 will be printed, rather than 3.

Смежные вопросы