我确定我在这里做一些蠢事,但我不确定是什么。我将匿名函数添加到数组中以供以后执行,并在for循环中创建它们,并使用可更改每次迭代的变量。
我希望记录的值为: HTTPS:server.net/a HTTPS:server.net/b
但我得到了: HTTPS:server.net/b HTTPS:server.net/b
看起来好像我重新定义它的功能时会覆盖它的最后一个版本,但我不确定为什么。我认为每个匿名函数都会有所不同。
为什么呢?我在这里做错了什么?
以下是一些示例代码:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = `https://server.net/${itemID}`;
var func = function(){
console.log(itemAccessUrl);
};
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
func();
}
答案 0 :(得分:1)
这是因为var
范围界定的性质。 var
不是块作用域,它是“悬挂的”,就像你在函数的顶部声明它一样。
您可以使用let
而不是var来声明itemAccessUrl,这是块作用域,但它取决于您需要的浏览器支持。 (话虽如此,你正在使用模板化字符串,所以你应该没问题)
答案 1 :(得分:1)
这里发生了什么?当您调用数组函数时,它们使用当前值itemAccessUrl
,即最后分配的字符串,使用char&#39; b&#39;。这是因为它们的调用在第一个for循环完成后发生。
您可以使用闭包:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = `https://server.net/${itemID}`;
var func = (function(param) {
return function () {
console.log(param);
};
})(itemAccessUrl);
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
f[j]();
}
或将您的函数绑定到当前参数:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = `https://server.net/${itemID}`;
var func = (function (param) {
console.log(param);
}).bind(null, itemAccessUrl);
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
f[j]();
}
此外,您必须更改第二个循环,调用f[j]();