可能重复:
Javascript closure inside loops - simple practical example
Javascript: closure of loop?
所以我希望结果是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 :(得分:1)
用另一个立即执行的函数包装内部函数并接收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 :(得分: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
的不同值。
答案 2 :(得分:0)
function buildJobs(list) {
var jobs = [];
list.forEach( function( item ){
jobs.push( function(){
alert(item);
});
});
return jobs;
}