2012-02-15 7 views
1

私の実験を適切なJavascriptでさらに進めると、別のメソッド(SayHello)を別の(WaitAndSayHello)メソッドから実行しようとしています。コールバックが含まれているので、私はbindを使って、各メソッドで 'this'がオブジェクトを参照していることを確認しました。バインドを使用してメソッドがオブジェクトを参照しているが、動作していないと思われる

コードは 'hello world'を出力し、 'Object#has no method' SayHello 'で2回目に失敗します。私は、console.logから、 'this'はイベントを参照していることがわかります。しかし、bind()を使ってこれを修正してはいけませんか?

bind()はどのように動作させることができますか?

また、私はこれをきちんとやりたいと思います。すなわち、複数の場所でオブジェクトの名前を参照することなく、

答えて

5

.bind()を「遅く呼び出す」ことはできません。あなたはまた、あなたがsetTimeout()に渡す匿名関数は、新しいコンテキストを作成し、そのため、独自のthisコンテキスト値を持つ

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

のように、関数の宣言時に、それを起動する必要があります。

あなたはどちらか

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

ありがとう@jAndy、それは事を完全に説明します。私はいつも 'var self = this'のことを少し見つけたので、2番目のソリューションを使用しました。私はそれが私の日常的なJSプログラミングの一部になるだろうと思っています。 – mikemaccana

+1

@nailer:大歓迎です。'.bind()'はES5に含まれているので、古いブラウザでは利用できない可能性があることに注意してください。しかし、そのシムに非常に簡単にそこに利用可能なシムがたくさんあります。 – jAndy

+0

PS。 @jAndy私は、setTimeoutから呼び出された関数上で1つのバインドだけを取り除くことができると思います。バインディングWaitAndSayHelloは不要です。あなたは次の男のためにあなたの答えを更新したいかもしれません。 – mikemaccana

1

あなたが使用する必要があります。

WaitAndSayHelloは、いくつかの引数を受け取った想像:

this.WaitAndSayHello.call(this); 

または

this.WaitAndSayHello.apply(this); 

applycallの違いは、あなたが呼ばれる関数に引数を渡す方法があります

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

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

を、あなたは配列として引数を渡す必要があります:、あなたが正常に機能を呼び出したとして、コンテキストの後に引数を渡す

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

編集

申し訳ありませんが、あなたのコードを間違って読んでいます。@ jAndyのanwserは本当に正しいロジックです。

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

のようにどのように、これは 'this'への参照を変更します、

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

または再.bind()を使用するような変数に「外this」への参照を保持する必要があります'setTimeout'コールバック内のDOMウィンドウ? – Niklas

+0

あなたは正しいです、私は間違ったコードを読んでいます。私はそれを修正しようとします –