4

我可能做错了什么,但在尝试将一些面向对象编程应用于 Javascript 时,我发现了一些有趣的行为。考虑以下

function Bug(element) {
    this.focusedCell = null;
    element.addEventListener('click', this.onClick, true);
};

Bug.prototype.onClick = function(event){
    console.log("this is: ");
    console.log(this);
};

当我从控制台调用该方法时,我看到了正确的“this”实例,但是当我单击文档中的元素时,我看到的是文档元素代替了该实例。所以......可能将事件侦听器与实例方法一起使用可能不是一个好主意,至少我这样做的方式是这样。

所以问题是:

  • 是否有可能有一个像这样的事件侦听器,它调用 javascript 对象的实例方法,同时在调用中保留实例?

  • 这样做有更好的模式吗?

编辑:除了 Chrome,我没有尝试过这个。但我想这种行为是一样的。

4

3 回答 3

6

有一个更好的模式,不需要太多的改变。我将首先显示代码。

function Bug(element) {
    this.focusedCell = null;
    // --------------------------------v----pass the object, not a function
    element.addEventListener('click', this, true);
};

// Implement the `EventListener` interface
Bug.prototype.handleEvent = function(event) {
    if (event.type === "click")
        this.onClick(event);
}

Bug.prototype.onClick = function(event) {
    console.log(JSON.stringify(this));         // '{"focusedCell":null}'
    console.log(event.currentTarget.nodeName); // "DIV"
};

通过添加handleEvent方法,我们Bug实现了EventListener接口。这允许我们将新Bug对象作为第二个参数传递给addEventListener()而不是函数。

现在,当"click"事件发生时,.handleEvent()将调用该方法,该方法中的值thisBug是绑定的对象。


由于this是对Bug实例的引用,显然它不再是对元素的引用。但这不是必需的,因为该元素可以通过event.currentTarget.

当然,Bug如果需要,您可以将元素直接添加到构造函数中的对象中。

演示:http: //jsfiddle.net/CnZTa/


于 2013-05-11T23:21:38.107 回答
5

您可以使用Function.prototype.bind创建一个绑定到您想要的任何值的侦听器:

function Bug(element) {
    this.focusedCell = null;
    element.addEventListener('click', this.onClick.bind(this), true);
};

较旧的(非 ES5)浏览器将需要一个 polyfill,例如来自MDN的那个。

于 2013-05-11T23:22:00.227 回答
1

这是 JavaScript 中的正常行为。您可以通过向侦听器传递函数来保留您的预期this

function Bug(element) {
    var self = this; // Store a reference to this
    this.focusedCell = null;
    element.addEventListener('click', function() {
        // in here this refers to element
        self.onClick(event);
    }, true);
};

Bug.prototype.onClick = function(event){
    console.log("this is: "); 
    console.log(this); // In here this refers the an instance of Bug.
};
于 2013-05-11T23:21:21.053 回答