如何在javascript事件处理程序中获取对象?

Yaz*_*Yaz 5 javascript closures event-handling

我试图在onclick事件处理函数中获取一个对象.

但它并没有像我期望的那样发挥作用.

例如,如果我运行此代码:

var entries = [{id: 1},{id: 2},{id: 3}];

for (var i = 0; i < entries.length; i++) {

    var entry = entries[i];

    document.getElementById(entry.id).onclick = function () { 
        console.log("this.id: " + this.id);
        console.log("entry.id: " + entry.id);
    };

}
Run Code Online (Sandbox Code Playgroud)

我的期望是:

this.id: 1
entry.id: 1

this.id: 2
entry.id: 2

this.id: 3
entry.id: 3
Run Code Online (Sandbox Code Playgroud)

但我得到的是:

this.id: 1
entry.id: 3

this.id: 2
entry.id: 3

this.id: 3
entry.id: 3
Run Code Online (Sandbox Code Playgroud)

为什么条目对象始终是id为3的条目?

如何在click事件处理程序中获取正确的条目对象?

Ate*_*ral 6

解决此问题的一种方法是:

var entries = [{id: 1},{id: 2},{id: 3}];

for (var i = 0; i < entries.length; i++) {

    var entry = entries[i];

    document.getElementById(entry.id).onclick = (function (id) {
        return function () { 
            console.log("this.id: " + this.id);
            console.log("entry.id: " + id);
        };
    })(entry.id);

}
Run Code Online (Sandbox Code Playgroud)

您可以使用自执行函数(其目的是提供entry.id将绑定的闭包)来返回绑定到特定id的新onclick处理程序.

如果不这样做,所有onclick处理程序都绑定到相同的条目变量,并以for循环期间收到的最后一个值结束.


Man*_*ish 2

这是因为 JavaScript 中闭包的工作方式。所有 3 个元素上的 onclick 引用存储相同的函数,该函数在循环之后具有指向最后一个条目的条目。于是就有了这样的结果。您可以通过将其包装在具有所需条目的另一个函数中来获得结果。以下是一种方法:

var entries = [{id: 1},{id: 2},{id: 3}];

for (var i = 0; i < entries.length; i++) {

    var entry = entries[i];

    function setOnClickHandler(entry) {
        document.getElementById(entry.id).onclick = function () { 
            console.log("this.id: " + this.id);
            console.log("entry.id: " + entry.id);
        };  
    }

    setOnClickHandler(entry);
}
Run Code Online (Sandbox Code Playgroud)

我已经就此写了一篇小文章。