9

我正在尝试为对象创建一个事件以使其监听它。考虑以下示例:

var moon;

moon = document.createEvent("Event");
moon.initEvent("Event",true,true);

var Dog = function (name) {
  this.name = name;
  
  document.addEventListener("Event",this.bark,false);
};
dog.prototype.bark = function() {
  console.log(this.name + ': Awooooooof Woof!');
};


var spot = new Dog("Spot");
var dot = new Dog("Dot");


//invoke
document.dispatchEvent(moon);

我期待收到如下输出:

现场:呜呜呜呜呜!

点:呜呜呜呜呜!

但我得到的是:

未定义:呜呜呜呜呜!

我的例子有什么问题?如何注册每个 Dog 实例都有的侦听器?

4

3 回答 3

10

在这一行

document.addEventListener("Event",this.bark,false);

您不绑定this.barkto的范围this。在 JavaScript 中, 的值this不取决于函数在哪里定义,而是从哪里调用。这意味着当您传递this.barkaddEventListener您时,将其与当前对象分离。

在prototype.js 和JQuery 等框架中,有绑定的快捷方式this,使用vanilla JavaScript 你可以这样做:

function bind(scope, fn) {
   return function() {
      return fn.apply(scope, arguments);
   }
}

接着:

document.addEventListener("Event",bind(this, this.bark),false);
于 2013-03-12T09:36:36.323 回答
4

您遇到的问题是this函数内部没有引用您要操作的对象。

bark在函数定义中添加函数怎么样?

var Dog = function (name) {
    this.name = name;    
    this.bark = function() {
        console.log(name + ': Awooooooof Woof!');
    };
    document.addEventListener("Event", this.bark, false);
};
于 2013-03-12T09:31:44.367 回答
0

问题

this关键字 insideDog.prototype.bark()指向调用该方法的对象。例如,当spot.bark()被调用时,this.name计算结果为spot.name,如下所示:

Dog.prototype.bark = function () {
    console.log(spot.name + ': Awooooooof Woof!');
};

当事件侦听器被添加到 Dog 的构造函数中时,document对象被告知侦听该事件,并Dog.prototype.bark()在它听到该事件时被告知调用。此设置正确完成,document对象在听到该事件时将调用正确的函数,

document对象实际调用 bark 函数时,问题就会发生。现在,this指向document对象,并this.name计算为document.name,如下所示:

Dog.prototype.bark = function () {
    console.log(document.name + ': Awooooooof Woof!');
};

document.name不存在,这就是为什么输出是:undefined: Awooooooof Woof!

修复

使用Function.prototype.bind()将提供的值绑定到函数的this关键字,如下所示:

document.addEventListener("Moon", this.bark.bind(this), false);
于 2016-09-21T19:55:12.820 回答