这可能是一个简单的问题,但是已经很晚了,我无法理解这一点。
这是我的代码
$(document).ready(function () {
var items = getNumber();
for (var i = 0; i < items.length; i++) {
var test = items[i].action;
test();
}
});
function getNumber()
{
var items = [];
for (var i = 0; i < 5; i++) {
var num = i * 10;
items.push({ id: i, number: num, action: function () { alert(i) } });
}
return items
}
有人可以向我解释为什么警报输出总是5?我希望alert参数在添加到数组时成为索引。好像它是动态的。
如果你也可以发布一个解决方案,我怎么能让它工作,我会非常感激
答案 0 :(得分:4)
这是JavaScript变量范围的一个常见问题:新变量仅在 中引入新的执行上下文,因此,在有问题的代码中,i
在之间共享动作回调。
无论如何,这是遵循标准习语的更正代码:
function getNumber()
{
var items = [];
for (var i = 0; i < 5; i++) {
var num = i * 10;
items.push({
id: i, number: num,
// _i is a new variable for each callback
action: (function (_i) {
// use separate (one per callback) _i variable
return function () { alert(_i) }
})(i) // pass in current value for loop
});
}
return items
}
或者,如果不喜欢所有嵌套,可以使用“命名”函数来执行相同的任务。关键是关闭是从新执行上下文创建(并从中返回),以便关闭不同的变量:
function getNumber()
{
function mkAction (i) {
return function () { alert(i) }
}
var items = [];
for (var i = 0; i < 5; i++) {
var num = i * 10;
items.push({
id: i, number: num,
action: mkAction(i)
});
}
return items
}
另一种方法是使用ES5中的Function.bind
:
function getNumber()
{
var items = [];
for (var i = 0; i < 5; i++) {
var num = i * 10;
items.push({
id: i, number: num,
action: (function (_i) { alert(_i) }).bind(null, i)
});
}
return items
}
(请注意,即使没有本机浏览器支持,也可以使用新的执行上下文/闭包来模拟Function.bind。请参阅MDC文档。)
另见: