1

这些功能有什么区别?为什么第一个工作,第二个没有按预期工作?

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);
    };
}
4

3 回答 3

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

这会围绕该值创建一个新的闭包,因为它在该迭代期间存在。当调用匿名函数时,它使用该本地值。

于 2013-03-28T22:33:41.990 回答
2

它被视为:

var item;

for (var i = 0; i < helpText.length; i++) {
    item = helpText[i];

    document.getElementById(item.id).onfocus = function() {
        showHelp(item.help);
    };
}

循环在任何焦点回调触发之前完成,此时item是分配的最后一项。

于 2013-03-28T22:33:56.917 回答
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 的最后一个循环将它的值设置为数组的最后一个值。

for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
于 2013-03-28T22:36:46.287 回答