面向对象的Javascript:事件处理

时间:2013-03-12 08:59:01

标签: javascript oop javascript-events

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

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);

我希望收到如下输出:

Spot: Awooooooof Woof!

Dot: Awooooooof Woof!

但我得到的是:

undefined: Awooooooof Woof!

我的例子出了什么问题?如何注册每个Dog实例的监听器? 提前谢谢!

3 个答案:

答案 0 :(得分:10)

在这一行

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

您没有将this.bark的范围绑定到this。在JavaScript中,this的值不依赖于函数的定义位置,而是取决于函数的调用位置。这意味着当您将this.bark传递给addEventListener时,您将其与当前对象分开。

在像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);

答案 1 :(得分:4)

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

如何在函数定义中添加函数bark

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

答案 2 :(得分:0)

问题

this内的Dog.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);
相关问题