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

需要说明:无法理解返回函数的javascript,javascript,function,window,closures,Javascript,Function,Window,Closures,我更像是一名C++/Java程序员,对Javascript还相当陌生。我一直在阅读Javascript这本好书 // 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

我更像是一名C++/Java程序员,对Javascript还相当陌生。我一直在阅读Javascript这本好书

     // 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 };
我希望有一个带有数字4的警报窗口。相反,警报窗口显示[object MouseeEvent]

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

您应该意识到的是,在第5-9行(顺便说一下,第7行在哪里?:)中创建了一个新函数,它将绑定为onclick的事件侦听器函数

见第9行:

}(i); 
这意味着立即调用上述函数,将i作为其函数参数传入,然后返回一个新函数


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

这是本书中的一个错误。他们试图演示一种可怕的(性能方面的)模式,即使用一个本来不必要的函数作用域来允许内联函数在外部作用域中围绕一个变量进行闭包,而这个变量由于没有在其他任何地方引用,因此变成了一种仅由内联函数引用的私有变量。如果
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'));
var add\u\u处理器=函数(节点){
对于(变量i=0;i

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

我试着使用它,并在我的 浏览者

window.onclick = function(i){
    return function(e){
        console.log("Inner function called");
        alert(e);
} }(4);
我希望出现一个带有数字4的警报窗口。相反,警报窗口显示[object MouseeEvent]

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

如果您想在其中生成正确值为
i
的警报,只需使用原始代码,但警报
i
,而不是
e

window.onclick = function(i){
    return function(e){
        console.log("Inner function called");
        alert(e);
} }(4);
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);
};
nodes[i].onclick = function (e) { alert(e); };