我对Javascript的理解是变量具有函数范围,而不是块范围,因此在块内声明的变量将被提升到它上面的函数。这个article给出了以下代码示例:
var arr = [1, 2, 3, 4]
for(var i = 0; i < arr.length; i++) {
var entry = arr[i];
setTimeout(function() {
console.log(entry);
}, 100);
}
文章指出代码被翻译成以下内容,因此变量entry
在每次迭代之间是通用的。结果是4
四次登录到控制台
var arr, i, len, entry;
arr = [1, 2, 3, 4]
for(i = 0; i < arr.length; i++) {
entry = arr[i];
setTimeout(function() {
console.log(entry);
}, 100);
}
我的问题是,如果我希望每次调用setTimeout
来记录arr
的不同值,我应该如何重写代码?
答案 0 :(得分:6)
您可以将setTimeout
更改为:
setTimeout(
(function()
{
var entry = arr[i];
return function() {console.log(entry);}
}
)()
);
这样,您创建了一个新范围,entry
就在该范围内。
你也可以这样做:
(function(e)
{
setTimeout(function(){console.log(e);});
}
)(entry);
这也创造了一个新的范围,e
所在。
又一个选择:
setTimeout(
(function(e)
{
return function() {console.log(e);};
}
)(entry);
);
在所有情况下,您都使用您立即调用的匿名函数,因此唯一的副作用是您正在创建新范围。
(编辑:为了便于阅读,重新格式化了一点,并添加了一些解释)