javascript关闭后使用匿名函数 [英] javascript closure after using anonymous function
问题描述
我正在努力处理闭包,我知道在循环中,新函数使用迭代器的最后一个值来引用闭包
I'm working on closure so hard, and I know that in the loop, new function refer closure using the last value of the iterator
因此以下函数的结果是三次item3 undefined
so the following function's result is three times "item3 undefined"
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])} );
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
然后我知道匿名函数可以诱使范围,所以我编辑第一个函数为:
and then I know that anonymous function can induce scope, so I edit the first function as:
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
(function(){
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])} );
})();
}
return result;
}
但结果是item1 undefined,item2 undefined,item3 undefined,
but the result is "item1 undefined", "item2 undefined", "item3 undefined",
所以我的问题是,为什么在我使用范围后结果仍然未定义?
so my question is, why is the result still undefined after I using scope?
推荐答案
假设这段代码的目的只是为了学习;你创建一个匿名函数,但你仍然指的是上一个作用域中的 i
,所以你不要改变任何东西从你最初写的第一个代码; i
仍然具有最后一个值( list.length
)。
Assuming that the purpose of this code is just to learn; you create an anonymous function but you're still referring to the i
in the previous scope, so you do not change anything from the first code you wrote initially; i
still has the last value (list.length
).
为了避免这种情况,您需要在您创建的函数范围内具有 i
的当前值:
In order to avoid that, you need to have the current value of i
in the scope of the function you've created:
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(function (index) {
return function() {alert(item + ' ' + list[index])}
}(i));
}
return result;
}
也可以使用 bind ,以部分应用:
Alternatively you can use bind, to have partial application:
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(function(index) {alert(item + ' ' + list[index])}.bind(null, i))
}
return result;
}
在ES6或启用JS 1.8.5的Firefox中,还可以让声明块作用域变量:
In ES6, or in Firefox with JS 1.8.5 enabled, you can use also let that declares block scope variable:
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
let index = i;
result.push(() =>alert(item + ' ' + list[index]));
}
return result;
}
在上一个示例中还有 ES6箭头功能。
这篇关于javascript关闭后使用匿名函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!