我正在尝试为对象创建一个事件让它听取它。请考虑以下示例:
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实例的监听器? 提前谢谢!
答案 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);