Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript中,在事件回调中检索对象的最佳方法是什么_Javascript_Oop_Dom Events - Fatal编程技术网

在JavaScript中,在事件回调中检索对象的最佳方法是什么

在JavaScript中,在事件回调中检索对象的最佳方法是什么,javascript,oop,dom-events,Javascript,Oop,Dom Events,通常我在JavaScript中使用对象来保存数据,但事件侦听器不允许辅助指针检索这些对象 在事件回调中检索对象指针的最佳方法是什么? (请不要使用第三方库) 例如: function MyClass() { this.number = Math.random(); this.button = document.createElement('div'); this.button.appendChild(document.createTextNode('Show number

通常我在JavaScript中使用对象来保存数据,但事件侦听器不允许辅助指针检索这些对象

在事件回调中检索对象指针的最佳方法是什么? (请不要使用第三方库)

例如:

function MyClass()
{
    this.number = Math.random();
    this.button = document.createElement('div');
    this.button.appendChild(document.createTextNode('Show number'));
    document.body.appendChild(this.button);
    // THIS FOLLOWING LINE REQUIRE CHANGES
    this.button.addEventListener('click', MyClass.prototype.listener);

}
MyClass.prototype.listener = function (e)
{
    // HERE, "THIS" DO NOT POINT TO MY OBJECT
    alert( this.number );
}
testMyClass1 = new MyClass();
testMyClass2 = new MyClass();
目前,我使用静态数组保存指针,但这很难维护:

//New constructor, first try    
function MyClass()
{
    this.number = Math.random();
    this.button = document.createElement('div');
    this.button.appendChild(document.createTextNode('Show number'));
    document.body.appendChild(this.button);
    if (undefined===MyClass.prototype.register) MyClass.prototype.register = [];
    this.id = MyClass.prototype.register.length;
    MyClass.prototype.register.push(this);
    this.callback = new Function( 'e', 
        'var self = MyClass.prototype.register[' + this.id + '];'+
        'MyClass.prototype.listener.call(self, e);'
    );
    this.button.addEventListener('click', this.callback);
}
注:

  • 我不想在构造函数中定义类函数,以避免为每个对象复制函数,这会占用大量内存。我的解决方案仍然保存了一个小函数
如果使用ES5:

this.button.addEventListener('click', MyClass.prototype.listener.bind(this));
如果不使用ES5,则为
函数.bind


请注意,这实际上创建了一个新的函数对象作为类的每个实例的处理程序,但是没有简单的方法可以避免这种情况。

您可以简单地使用函数创建一个包含较少参数的包装器。换句话说,

更改:

this.button.addEventListener('click', MyClass.prototype.listener);
致:

可以使用设置事件处理程序的上下文

function MyClass()
{
    this.number = Math.random();
    this.button = document.createElement('div');
    this.button.appendChild(document.createTextNode('Show number'));
    document.body.appendChild(this.button);
    // THIS FOLLOWING LINE WAS CHANGED
    this.button.addEventListener('click', MyClass.prototype.listener.bind(this));

}
MyClass.prototype.listener = function (e)
{
    // HERE, "THIS" DO NOT POINT TO MY OBJECT
    alert( this.number );
}
testMyClass1 = new MyClass();
testMyClass2 = new MyClass();

一种非常简单而优雅的方法是让对象实现EventListener接口

为此,您的对象只需要有一个
handleEvent()
方法

MyClass.prototype.handleEvent = function(event) {
     switch (event.type) {
     case "click":
          return this.listener(event);
     default:
          throw "No handler for " + event.type
     }
}
然后你只需传递对象本身

//                                      v--pass the object instead of a function
this.button.addEventListener('click', this);
因此
handleEvent
中的
this
是预期的对象,因此您可以调用您的对象方法

//                                      v--pass the object instead of a function
this.button.addEventListener('click', this);