2013-03-12 74 views
9

我想创建一个事件来让对象听它。请看下面的例子:面向对象的Javascript:事件处理

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! 

什么是错我的例子吗?我怎样才能注册一个狗的每个实例都有的侦听器? 在此先感谢!

回答

9

在这一行

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

你没有的this.bark范围绑定到this。在JavaScript中,this的值不取决于函数的定义位置,而取决于函数的调用位置。这意味着当你通过this.barkaddEventListener时,你将它从当前对象中分离出来。

在这样的prototype.js和JQuery有绑定this快捷方式框架,与香草的JavaScript,你可以做这样的:

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

然后:

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

非常感谢! 我想通过jQuery实现它,但我认为你的解决方案更加优雅。 – Alessandro 2013-03-12 09:58:40

4

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

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

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

的问题

this关键字,内Dog.prototype.bark()点t o调用该方法的对象。例如,当spot.bark()被调用,this.name计算结果为spot.name,像这样:

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

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

稍后当document对象实际调用树皮函数时会发生此问题。现在,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);