2008-10-23 8 views
19

JavaScript에서 클래스 멤버를 이벤트 처리기로 사용하는 가장 좋은 방법이나 일반적인 방법이 있습니까?JavaScript의 이벤트 처리기로 클래스 메서드?

는 다음과 같은 간단한 예를 고려해

<head> 
    <script language="javascript" type="text/javascript"> 

     ClickCounter = function(buttonId) { 
      this._clickCount = 0; 
      document.getElementById(buttonId).onclick = this.buttonClicked; 
     } 

     ClickCounter.prototype = { 
      buttonClicked: function() { 
       this._clickCount++; 
       alert('the button was clicked ' + this._clickCount + ' times'); 
      } 
     } 

    </script> 
</head> 
<body> 
    <input type="button" id="btn1" value="Click me" /> 
    <script language="javascript" type="text/javascript"> 
     var btn1counter = new ClickCounter('btn1'); 
    </script> 
</body> 

은 buttonClicked가 호출되는 이벤트 핸들러를하지만, _clickCount 멤버에 액세스 할 수 없습니다, 또는 다른 개체에 대한 점.

이런 종류의 문제에 대한 유용한 팁이나 기사/자료가 있습니까?

답변

17
ClickCounter = function(buttonId) { 
    this._clickCount = 0; 
    var that = this; 
    document.getElementById(buttonId).onclick = function(){ that.buttonClicked() }; 
} 

ClickCounter.prototype = { 
    buttonClicked: function() { 
     this._clickCount++; 
     alert('the button was clicked ' + this._clickCount + ' times'); 
    } 
} 
+0

해결책 주셔서 감사합니다. 나는 또한 더 큰 그림 패턴, 습관 등을 이해하려고 노력하고있다. – JacobE

+5

이 것은 훌륭합니다 : http://ejohn.org/apps/learn/ – pawel

+8

이것은 좋은 예입니다. 그러나이 답변은 왜 여기가 초보자들에게 좋은 해결책인지에 대한 설명과 함께 더 낫습니다. –

5

OnClick 속성에 직접 부착 된 기능 소자의 실행 콘텍스트의 this 속성을 가리키는 것이다.

당신은 (라 .NET에서 위임) 다음 폐쇄해야 객체의 특정 인스턴스에 대해 실행하는 요소 이벤트에 필요로 할 때 : -

function MyClass() {this.count = 0;} 
MyClass.prototype.onclickHandler = function(target) 
{ 
    // use target when you need values from the object that had the handler attached 
    this.count++; 
} 
MyClass.prototype.attachOnclick = function(elem) 
{ 
    var self = this; 
    elem.onclick = function() {self.onclickHandler(this); } 
    elem = null; //prevents memleak 
} 

var o = new MyClass(); 
o.attachOnclick(document.getElementById('divThing')) 
+0

이것은 정확히 내가 찾고 있었던 것이다! 고맙습니다! – Jeremy

0

모르겠다을 왜 Function.prototype.bind 여기 아직 언급되지 않았습니다. 그래서 난 그냥 여기를 떠날거야, 당신은 시도 할 수

ClickCounter = function(buttonId) { 
    this._clickCount = 0; 
    document.getElementById(buttonId).onclick = this.buttonClicked.bind(this); 
} 

ClickCounter.prototype = { 
    buttonClicked: function() { 
     this._clickCount++; 
     alert('the button was clicked ' + this._clickCount + ' times'); 
    } 
} 
1

당신은 함수 그 후

function doIt() { 
    this.f =() => { 
    console.log("f called ok"); 
    this.g(); 
    } 
    this.g =() => { 
    console.log("g called ok"); 
    } 
} 

의 어휘 범위에 바인딩 지방 화살표 구문을 사용할 수 있습니다)

var n = new doIt(); 
setTimeout(n.f,1000); 

babel에서 시도하거나 브라우저가 jsFiddle에서 ES6을 지원할 수 있습니다.

불행히도 ES6 클래스 -syntax는 어휘 적으로 이것에 바인드 된 함수를 생성하는 것을 허용하지 않습니다. 나는 개인적으로 그렇게 할 수도 있다고 생각합니다. 편집 : experimental ES7 feature to allow it 것 같습니다.

관련 문제