2012-02-15 2 views
1

자바 스크립트에서 실험을 진행하면서 다른 메소드 (WaitAndSayHello)에서 하나의 메소드 (SayHello)를 실행하려고합니다. 콜백이 관련되어 있으므로 각 메서드에서 'this'가 해당 개체를 참조하는지 확인하기 위해 bind을 사용했습니다.bind를 사용하여 메소드가 객체를 참조하는지 확인하지만 작동하지 않는 것 같습니다

pretendThingConstructor = function (greeting) { 
    this.greeting = greeting; 

    this.SayHello = function() { 
     console.log(this.greeting); // Works 
    }; 

    this.WaitAndSayHello = function() { 
     setTimeout(function() { 
      console.log(this) 
      this.SayHello() // Fails 
     }, 500); 
    } 
    this.WaitAndSayHello.bind(this); // This bind() doesn't seem to work 
} 


var pretend_thing = new pretendThingConstructor('hello world'); 
pretend_thing.SayHello(); 
pretend_thing.WaitAndSayHello(); 

코드는 'hello world'를 인쇄 한 다음 'Object # has no method'SayHello '로 두 번째 실패합니다. console.log에서 'this'가 이벤트를 참조하고 있음을 알 수 있습니다. 그러나 bind()를 사용해서는 안된다.

어떻게해야 bind() 작업을 할 수 있습니까?

또한이 작업을 명확하게 수행하고 싶습니다. 즉, 여러 위치에서 개체 이름을 참조하지 않아도됩니다.

답변

5

.bind()에 "늦게 전화를 걸"수 없습니다. 당신은 또한 당신이 setTimeout()에 전달하는 익명 함수는 새로운 컨텍스트를 생성하고, 따라서 자신의 this 컨텍스트 값이

this.WaitAndSayHello = function() { 
    setTimeout(function() { 
     console.log(this) 
     this.SayHello() // Fails 
    }, 500); 
}.bind(this) 

처럼, 함수 선언시를 호출해야합니다.

당신에게 어느 방법이에`this` 참조를 바꿀 것

this.WaitAndSayHello = function() { 
    setTimeout(function() { 
     console.log(this) 
     this.SayHello() // succeeds 
    }.bind(this), 500); 
}.bind(this) 
+0

@jAndy, 그 일을 완벽하게 설명합니다. 나는 항상 'var self = this'에 대해 뭔가를 발견했다. 그래서 나는 두 번째 해결책을 사용했다. 나는 그것이 나의 일상적인 JS 프로그래밍의 일부가 될 것이라고 생각한다. 다시 감사한다. – mikemaccana

+1

@nailer : 대환영.'.bind() '는 ES5의 일부이므로 오래된 브라우저에서는 기본적으로 사용할 수 없다는 것을 기억하십시오. 그러나 매우 심플하고 거기에 많은 shim이 있습니다. – jAndy

+0

PS. @jAndy 나는 setTimeout에서 호출 된 함수에 대해서 단 하나의 바인드 만 제거 할 수 있다고 생각합니다. 바인딩 WaitAndSayHello는 필요하지 않습니다. 다음 사람에 대한 대답을 업데이트하고 싶을 수도 있습니다. – mikemaccana

1

당신은 사용해야

: WaitAndSayHello 일부 인수를받은 상상 :

this.WaitAndSayHello.call(this); 

또는

this.WaitAndSayHello.apply(this); 

applycall의 차이는 당신이 호출 된 함수에 인수를 전달하는 것이 방법입니다

this.WaitAndSayHello = function(toWho, helloMessage){ 
... 
} 

당신은 일반적으로 함수를 호출했다으로, 당신은, 문맥 후 인수를 전달합니다 : apply

this.WaitAndSayHello.call(this, 'Bob', 'Hello'); 

, 당신은 배열로 인수를 전달하는 것 :

this.WaitAndSayHello.apply(this, ['Bob', 'Hello']); 

편집

미안하지만 코드를 잘못 읽었습니다. @ jAndy의 anwser는 내 논리를 사용하여 다음과 같이 할 수 있습니다.

+1

처럼

this.WaitAndSayHello = function() { var self = this; setTimeout(function() { console.log(self) self.SayHello() // succeeds }, 500); }.bind(this) 

같은 변수에 "외부 this"에 대한 참조를 유지하거나 다시 .bind()를 사용할 필요가 'setTimeout' 콜백 내의 DOM 윈도우? – Niklas

+0

당신 말이 맞아, 나는 코드를 잘못 읽었다. 나는 그것을 고치려고 노력할 것이다 –

관련 문제