2011-11-03 3 views
2

누구나 내 'showDiv_boo'가 클래스 메서드 내에서 정의되지 않은 이유를 알 수 있습니까? 클래스 메서드에 액세스 할 수 없습니다.Javascript 클래스 상속

Here's 내 클래스의 속성 및 방법 '블링크'클래스 :

function Blink(div) { 
    this.div = div 
} 
Blink.prototype.counter = 0 
Blink.prototype.showDiv_boo = true 
Blink.prototype.showDiv = function() { 
    this.div.style.visibility = 'visible' 
} 
Blink.prototype.hideDiv = function() { 
    this.div.style.visibility = 'hidden' 
} 
Blink.prototype.startEngine = function() { 
    if (this.showDiv_boo) { 
     this.showDiv() 
    } else if (!this.showDiv_boo) { 
     this.hideDiv() 
    } 
    this.showDiv_boo = !this.showDiv_boo 
    this.counter++ 
} 
Blink.prototype.startEffect = function() { 
    this.idEffect = setInterval(this.startEngine, 1000/45) 
} 

그래서, 내가 만드는 경우 :

_blink = new Blink(myDiv); 
_blink.startEffect(); 

당신은 ... 변수 'showDiv_boo'를 테스트 할 수 있습니다 메서드 내에서 정의되지 않습니다.

심지어 메서드 내 showDiv_boo를 true로 설정하면 내 클래스의 showDiv 또는 hideDiv 메서드를 호출하지 않게됩니다.

누구나?

감사합니다 :)

답변

3

을 수행해야합니다에서 호출을 래핑하는 익명 함수를 사용

  1. 사용 var selfself.startEngine()
  2. 를 통해 메소드를 호출 [1] 즉 function(){ self.startEngine(); }

이 때를하기 때문에 this.startEngine 또는 self.startEngine을 전달하면 그냥 this을 지정하지 않고 startEngine 함수를 전달하는 것입니다. 두 경우 모두 gl에 의해 제공됩니다. obal 문맥은 DOMWindow입니다.

예를 제공하기 위해 ...

function startEngine() { 
    ...code omitted... 
}; 

Blink.prototype.startEngine = startEngine; 

Blink.prototype.start = function() { 
    setTimeout(startEngine, 0);  // obviously wrong, what is this? 
    setTimeout(Blink.startEngine, 0); // actually the same as line above, although not as obvious 
    setTimeout(startEngine.bind(this), 0); // works correctly 
} 

프로토 타입에 코드를 추가하고 작동 익명 함수에 사용하는 경우 예상대로하기 위해 노력하지만, 그냥 콜백으로 Blink.startEngine를 사용하는 경우 그것은 정확히입니다 startEngine을 사용할 때와 마찬가지로 두 번째 경우에만 호출되는 객체가 없으므로 더 분명히 잘못됩니다. 즉, this이 컨텍스트에서 제공되는 것이 무엇이든 기대할 수 있습니다.당신은 익명 함수를 사용하지 않고이 작업을 수행 할 수

다른 방법은 것 같은 명시 적으로 익명 함수를 작성하고 self.startEngine()에 전화를 포장 같은 올바른 this으로 startEngine를 호출하는 함수를 반환

Blink.startEngine.bind(self) 

Heres는 바이올린에 대한 링크는 차이가 주위에 재생하려면 : http://jsfiddle.net/bonza_labs/MdeTF/

+0

그것은 올바르게 작동합니다. 감사합니다 :) –

5

startEnginesetInterval에서 호출되는 이유. 이 콜백 호출 방법은 startEnginethis에 대해 startEffect이 아닌 다른 값을 갖도록합니다. 콜백에서 유지하려면 this을 저장해야합니다. 예를 들어. 다음 작업을 수행 할 경우

Blink.prototype.startEffect = function() { 
    var self = this; 
    self.idEffect = setInterval(function() { self.startEngine(); }, 1000/45); 
}; 
+0

안녕하세요. 'var self'와 같은 것을 사용하려고했습니다. showDiv_boo는 startEngine 메소드 내부에서 정의되지 않습니다. –

+0

익명 함수로 감싸지 않을 수도 있습니다. 두 가지 모두하는 것이 중요합니다. 익명 함수를 사용하지 않으면'self.startEngine'과'this.startEngine'은 완전히 동일합니다. 자세한 설명은 내 대답을 참조하십시오. – craigb

0

, 당신은이

var x = new Blink('hello'); 
x.showDiv_boo 

자바 스크립트가 프로토 타입 상속을 사용하여 정의되어 있습니다. showDiv_boo는 현재있는 Blink 인스턴스 내에서 명시 적으로 정의되지 않을 수 있지만 Blink가 상속하는 프로토 타입 내에 존재합니다. 객체 내에서 showDiv_boo를 참조하면 Javascript 엔진은 객체가 해당 이름의 구성원을 소유하고 있지 않음을 인식하고 프로토 타입을 검사합니다.

+0

'startEngine'메소드에서 'showDiv_boo'에 액세스하려면 어떻게해야합니까? 감사합니다 :) –

0

을 설정과 함께 시간적 변수는 해당 변수로 startEngine() 함수를 호출해야합니다, this 저장하기 :

Blink.prototype.startEffect = function(){ 
    var self = this; 
    self.idEffect = setInterval(function(){ self.startEngine.call(self); }, 1000/45); 
} 

startEngine에서 기본적으로 변수 self로 함수를 호출 .call(self), 그래서 변수 this 올바른 하나가 될 것입니다.

+0

'self.startEngine()'을 호출하는 것만으로도 호출을 self에 다시 명시 적으로 바인드 할 필요는 없습니다. – craigb