2014-03-06 1 views
0

일반적으로 데이터를 저장하기 위해 JavaScript의 객체를 사용하지만 이벤트 수신기는 보조 포인터가 이러한 객체를 검색 할 수 없도록합니다.JavaScript의 이벤트 콜백에서 객체를 검색하는 가장 좋은 방법은 무엇입니까

이벤트 콜백에서 객체 포인터를 검색하는 가장 좋은 방법은 무엇입니까? (제 3의 라이브러리는 만족하지 않고)

예 : 현재

function MyClass() 
{ 
    this.number = Math.random(); 
    this.button = document.createElement('div'); 
    this.button.appendChild(document.createTextNode('Show number')); 
    document.body.appendChild(this.button); 
    // THIS FOLLOWING LINE REQUIRE CHANGES 
    this.button.addEventListener('click', MyClass.prototype.listener); 

} 
MyClass.prototype.listener = function (e) 
{ 
    // HERE, "THIS" DO NOT POINT TO MY OBJECT 
    alert(this.number); 
} 
testMyClass1 = new MyClass(); 
testMyClass2 = new MyClass(); 

, 나는 포인터를 저장하는 정적 배열을 사용하지만 유지하기 어렵다 :

//New constructor, first try  
function MyClass() 
{ 
    this.number = Math.random(); 
    this.button = document.createElement('div'); 
    this.button.appendChild(document.createTextNode('Show number')); 
    document.body.appendChild(this.button); 
    if (undefined===MyClass.prototype.register) MyClass.prototype.register = []; 
    this.id = MyClass.prototype.register.length; 
    MyClass.prototype.register.push(this); 
    this.callback = new Function('e', 
     'var self = MyClass.prototype.register[' + this.id + '];'+ 
     'MyClass.prototype.listener.call(self, e);' 
    ); 
    this.button.addEventListener('click', this.callback); 
} 

참고 :

  • 전이 함수의 생성을 피하기 위해 생성자 내에 클래스 함수를 정의하고 싶지 않습니다. 많은 양의 메모리를 필요로합니다. 어쨌든 내 솔루션은 여전히 ​​작은 기능을 저장합니다. ES5를 사용

답변

5

경우 :

this.button.addEventListener('click', MyClass.prototype.listener.bind(this)); 

Function.bind에 대한 ES5, get a shim를 사용하지 않는 경우.

실제로이 클래스의 각 인스턴스에 대한 처리기로 새 함수 개체를 만들지 만 쉽게 피할 수있는 방법은 없습니다.

+0

너무 빨리 나를 위해! –

0

간단히 함수를 사용하여 더 적은 수의 매개 변수를 사용하는 래퍼를 만들 수 있습니다. 즉,

변경 :

this.button.addEventListener('click', MyClass.prototype.listener); 

사람 :

var self = this; 
this.button.addEventListener('click', function() { self.listener(); }); 
2

당신은 이벤트 핸들러

function MyClass() 
{ 
    this.number = Math.random(); 
    this.button = document.createElement('div'); 
    this.button.appendChild(document.createTextNode('Show number')); 
    document.body.appendChild(this.button); 
    // THIS FOLLOWING LINE WAS CHANGED 
    this.button.addEventListener('click', MyClass.prototype.listener.bind(this)); 

} 
MyClass.prototype.listener = function (e) 
{ 
    // HERE, "THIS" DO NOT POINT TO MY OBJECT 
    alert(this.number); 
} 
testMyClass1 = new MyClass(); 
testMyClass2 = new MyClass(); 
1

매우 간단하고 우아한의 컨텍스트를 설정하는 Function.bind을 사용할 수 있습니다 방법은 객체가 EventListener 인터페이스를 구현하도록 만드는 것입니다.

이렇게하려면 개체에 handleEvent() 메서드가 있어야합니다.

MyClass.prototype.handleEvent = function(event) { 
    switch (event.type) { 
    case "click": 
      return this.listener(event); 
    default: 
      throw "No handler for " + event.type 
    } 
} 

그러면 객체 자체를 전달합니다. 당신이 당신의 객체 메소드를 호출 할 수 있도록

//          v--pass the object instead of a function 
this.button.addEventListener('click', this); 

그래서 handleEvent에서 this가 예상되는 개체입니다.

관련 문제