2011-12-28 5 views
0

Можно создать дубликат:
Javascript closure inside loops - simple practical example
Javascript: closure of loop?Javascript замыкание в цикле

поэтому я хотел бы, чтобы результаты были 1,2,3 вместо 3,3,3 , Как установить контекст/область, чтобы задания использовали правильно «i»?

function buildJobs(list) { 
    var jobs = []; 
    for (var i = 0; i < list.length; i++) { 
    var item = list[i]; 
    jobs.push(function() {alert(item)}); 
    } 
    return jobs; 
} 

function testJobs() { 
    var jobs = buildJobs([1,2,3]); 
    for (var j = 0; j < jobs.length; j++) { 
    jobs[j](); 
    } 
} 
+0

не является точной копией, но та же идея. – hvgotcodes

+1

@hvgotcodes хорошо существует более 9000 точных копий, поэтому на самом деле не имеет значения, если это не так: D – Esailija

+0

именно его удивительный, сколько раз этот вопрос задают .... – hvgotcodes

ответ

1

Wrap внутренняя функция с другой функцией, которая выполняется сразу же и получает i в качестве аргумента:

function buildJobs(list) { 
    var jobs = []; 
    for (var i = 0; i < list.length; i++) { 
    var item = list[i]; 
    (function(i) { 
     jobs.push(function() {alert(list[i])}); 
    })(i); 
    } 
    return jobs; 
} 

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

1

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

function buildJobs(list) { 
    var jobs = []; 
    for (var i = 0; i < list.length; i++) { 
    (function(i) { 
     var item = list[i]; 
     jobs.push(function() {alert(item)}); 
    })(i); 
    } 
    return jobs; 
} 

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

0
function buildJobs(list) { 
    var jobs = []; 

    list.forEach(function(item){ 
     jobs.push(function(){ 
      alert(item); 
     }); 
    }); 

    return jobs; 
} 

forEach

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