2013-03-12 55 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);