这些功能有什么区别?为什么第一个工作,第二个不能按预期工作?
http://jsfiddle.net/GKDev/x6pyg/(这有效)
http://jsfiddle.net/GKDev/bv4em/(这不是)
我正在尝试遍历输入元素并在它们上添加onfocus事件:
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
};
}
答案 0 :(得分:2)
在非工作示例中,当调用匿名函数时,item
具有for
循环执行完后所持有的最后一个值。那是因为这个变量属于包含for
循环的父函数。
在您的工作示例中,您创建了一个新函数,传递当前值item
,如下所示:
function (help) {
return function () {
showHelp(help); // <-- This will be the value enclosed in this anonymous function
};
}(item.help); // <-- Calls an anonymous function passing in the current value
这会在该迭代期间存在一个围绕该值的新闭包。调用匿名函数时,它使用该本地值。
答案 1 :(得分:2)
它被视为:
var item;
for (var i = 0; i < helpText.length; i++) {
item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
};
}
在任何焦点回调触发之前,循环已完成,此时item
是指定的最后一项。
答案 2 :(得分:1)
实际上很容易。
在第一种情况下,您将在闭包内传递item.help,该闭包充当本地副本。它就像一个范围的囚犯。外面发生了什么,无人问津。
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function (help) {
return function () {
showHelp(help);
};
}(item.help);
}
在第二个中,没有闭包保留item的值,这意味着当item被计算时,它会计算到它的实际值,即:数组的最后一个元素,因为for set的最后一个循环它的值是数组的最后一个值。
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}