需要说明:无法理解返回函数的javascript

Explanation needed : Cannot understand javascript returning a function

本文关键字:返回 函数 javascript 说明      更新时间:2023-12-27

我更像是一名C++/Java程序员,对Javascript相当陌生。我一直在读Javascript的好部分书。在关于函数的一章中,作者引用了一个例子,通过执行以下将事件侦听器附加到DOM中的节点

     // When you click on a node, an alert box will display the ordinal of the node.
1 var add_the_handlers = function (nodes) {
2        var i;
3        for (i = 0; i < nodes.length; i += 1) {
4            nodes[i].onclick = function (i) {
5                return function (e) {
6                    alert(e);
7                };
8            }(i);
9        
10 };

上述函数的目的是向DOM中的所有节点添加onclick事件处理程序,以便当单击任何节点时,它都会提醒分配给它的编号或它的序号。

我听不懂第5行到第8行。我理解函数(onclick=函数(I)…)立即调用,并以i作为其论据。但是,这个"i"是如何传递给正在返回的函数的呢?"e"是如何获得稍后被提醒的"i"的值的?

我试着玩它,并在我的浏览器中运行了以下代码

window.onclick = function(i){
    return function(e){
        console.log("Inner function called");
        alert(e);
    }
}(4); 

我本以为会有一个数字为4的警报窗口,但警报窗口显示的却是[object MouseEvent]。

如果有人向我解释一下,我将不胜感激。感谢

这是书中的一个错误。他们试图展示一种糟糕的(性能方面的)模式,即使用一个不必要的函数范围来允许内联函数围绕外部范围中的变量闭合,因为它在其他任何地方都没有被引用,所以它变成了内联函数只引用的一种私有变量。如果i变量确实被用作alert()调用的参数,那么代码就会完成它的工作:

var add_the_handlers = function(nodes) {
    for (var i = 0; i < nodes.length; ++i) {
        nodes[i].onclick = function(i) {
            return function() {
                alert(i);
            };
        }(i);
    } // end for
};
add_the_handlers(document.getElementsByTagName('div'));

http://jsfiddle.net/pzht9mLu/

在这本书的代码中,成为onclick处理程序的内联函数并没有围绕外部范围中的函数参数i闭合,而是围绕任何闭合。相反,在alert()调用中用作参数的e变量绑定到内联函数的函数参数e(这就是为什么不发生闭包的原因;只有当函数范围内的变量引用未能绑定到范围内的任何本地,而是绑定到外部范围内的变元时,才会发生闭包)。因为函数最终充当了事件处理程序,所以它的参数e被设置为等于发起回调的Event对象(如果发生回调以及何时发生回调),这就是您在警报消息中看到这一点的原因。

您应该意识到的是,在第5-9行(其中的数字7 btw?:)中创建了一个新函数,该函数将绑定为onclick的事件侦听器函数。

参见第9行:

}(i); 

这意味着上面的函数立即被调用,将i作为其函数参数传入,然后返回一个新函数。

例如,如果您在这个内部函数中使用i的值,它将被捕获在闭包中,因此onclick函数将可以访问它,即使它是从完全不同的范围调用的。

我试着玩它,并在我的浏览器

window.onclick = function(i){
    return function(e){
        console.log("Inner function called");
        alert(e);
} }(4);

我本以为会有一个数字为4的警报窗口,但警报窗口显示的却是[object MouseEvent]。

从未使用参数i。该警报生成e,它是onclick事件处理程序的参数。它是一个MouseEvent对象。

var add_the_handlers = function (nodes) {
var i;
for (i = 0; i < nodes.length; i += 1) {
    nodes[i].onclick = function (i) {
        return function (e) {
            alert(e);
        };
     }(i);
};

上述函数的目的是将onclick事件处理程序添加到DOM中的所有节点,这样当任何节点单击它会提醒分配给它的编号或它的序号。

我听不懂第5行到第8行。我知道函数(onclick=函数(i)…)立即与我通话作为其论据。但是这个"i"是如何传递给是否被退回?"e"如何获得稍后的"i"的值被提醒?

i不会传递给第二个函数,并且永远不会在当前代码中显示。你现在所做的实际上与此没有什么不同:

nodes[i].onclick = function (e) { alert(e); };

如果您想生成一个具有正确值i的警报,您只需使用原始代码,但要提醒i而不是e