2015-05-25 46 views
23

在此ES6腳本「的addEventListener」,單擊事件不工作,因爲sayHello函數調用this.elm<div>)爲thisES6類:訪問「這個」施加於法

如何將事件與方法關聯而不會鬆動範圍?

class player{ 
    constructor(name){ 
    this.name = name; 
    this.elm = document.createElement('div'); 
    this.elm.addEventListener('click', this.sayHello); 
    } 
    sayHello(){ 
    console.log(this.name + ' say: "hello!"'); // 'undefined say 'hello!"'; 
    } 
    kill(){ 
    console.log(`RIP ${this.name} :'(`); 
    this.elm.addClass('dead'); 
    this.elm.removeEventListener('click', this.sayHello); 
    } 
} 

回答

63

這是一個普遍的JS問題,但它的核心是

this.elm.addEventListener('click', this.sayHello); 

不超過

var fn = this.sayHello; 
this.elm.addEventListener('click', fn); 

你傳入一個函數作爲事件處理程序不同,但還沒有確保當fn被稱爲this將被設置爲您想要的值。最簡單的方法來做到這一點在ES5是

this.elm.addEventListener('click', this.sayHello.bind(this)); 

或ES6,用箭頭功能:然而,這兩種解決方案會破壞你的(已略微沙啞的)邏輯

this.elm.addEventListener('click', evt => this.sayHello(evt)); 

kill因爲

this.elm.removeEventListener('click', /* what? */); 

您不必到你了附加功能的任何引用,所以你沒有刪除的事件處理程序的方式。

我建議兩個選項:

// Create a new function that is bound, and give it a new name 
// so that the 'this.sayHello()' call still works. 
this.boundSayHello = evt => this.sayHello(evt); 
this.elm.addEventListener('click', this.boundSayHello); 
this.elm.removeEventListener('click', this.boundSayHello); 

// Bind the function with the same name and use `.bind` instead of the 
// arrow function option. 
this.sayHello = this.sayHello.bind(this); 
this.elm.addEventListener('click', this.sayHello); 
this.elm.removeEventListener('click', this.sayHello); 
+0

謝謝,這是我用的,但每個對象需要有需要回調HTTP每個綁定功能的對象指向: //codepen.io/yukulele/pen/yNVVxV/?editors=001 –