2012-04-16 14 views
1

私はJavascriptを使い慣れていないので、オブジェクトの関数を定義するためのプロパティキーワードを発見しました。オブジェクトを使ってwebsocketの実験をリファクタリングしようとしましたが、動作させることができません。javascriptで関数を割り当てる方法は?

これは(ないオブジェクト)に動作しません:

var ws = new WebSocket(something, somethingelse); 
ws.onopen = function() { 
    ws.send("hello"); 
    console.log("works"); 
} 

しかし、これにはない:

function MyObject() { 
    this.ws = new WebSocket(something, somethingelse); 
    this.ws.onopen = this.onOpen; 
} 

MyObject.prototype.onOpen = function() { 
    this.ws.send("hello"); // undefined! 
}; 

なぜ未定義WSのですか?私はonOpen関数を間違って割り当てていますか?

+2

あなたは 'new'キーワードを使用していますか?ここに間違ったものがたくさんあります。あなたは正確に何をしようとしていますか? –

+1

「プロパティキーワード」とは何ですか? –

+0

onOpen関数はWebSocketオブジェクトによって呼び出され、 "this"は実際にはWebSocketオブジェクトになりますが、MyObjectではなくなります。 (*もし私が物事を乱していないなら.. *) – moka

答えて

6

関数を正しく割り当てている(関数を割り当てる方法は1つだけです)、問題は関数のコンテキストが変更されることです。 1

this.ws.onopen = this.onOpen; 

可能性::

は、今、私が想定し、WebSocket内部に、どこかでこの機能は、開口接続への応答として呼び出されます(イベントハンドラのような

この行を考えてみましょう)、おそらく同様

this.onopen(); 

What this refers to inside a function is determined by how a function is called on run time<-このリンクを読む、それは多くの助けになります)。定義時にバインドされていません。あなたの場合、thisWebSocketインスタンスを指します。だから、内部に、このように呼ばれるMyObject.prototype.onOpen内、thisWebSocketws性質を持っていない場合、およびないMyObjectインスタンス、this.wsを参照する場合

これは、2つの方法で解決することができます:

  1. thisが既にthis.wsを指しているので、あなたがthisに直接sendを呼び出すことができます。

    MyObject.prototype.onOpen = function() { 
        this.send("hello"); 
    }; 
    
  2. あなたはMyObject.prototype.onOpen内部thisは常にしたい場合MyObjectインスタンスを参照するには、インスタンスへの明示的な参照を保持する必要があります。閉鎖を通じて:onOpen内部今

    var self = this; 
    this.ws.onopen = function() { 
        self.onOpen(); 
    }; 
    

    thisあなたは、コンストラクタでそれを設定すると同じように、プロパティwsを持ってMyObjectインスタンスを参照します。

    this.ws.onopen = this.onOpen.bind(this); 
    

可能性2:のECMAScript 5を支持ブラウザで

、機能が既にこの技術のための方法を有する、.bind()と呼ば

またということかもしれないWebSocketこのようにしてonopenを呼び出します。

その場合
this.onopen.call(null); 

thisコードは(それが問題である任意の場合には、問題ではない)厳密モードで実行するか否かに応じて、windowを参照するであろういずれかまたはundefinedあろう。

この状況は、最初の可能性から2番目の解決策でしか解決できませんでした。


最初の例はなぜ機能しますか?この場合

var ws = new WebSocket(something, somethingelse); 
ws.onopen = function() { 
    ws.send("hello"); 
    console.log("works"); 
} 

、あなたがws.onopenに割り当てる機能がwsまた、このスコープで定義された変数の上に閉じ、閉鎖です。この意味では、問題を解決する第2の方法と似ていますが、

ws.onopen = function() { 
    this.send("hello"); 
    console.log("works"); 
} 

などと考えられます。

+0

そう、私はWebSocketsを使っていたときと全く同じことをしました。 –

+0

ああ、最も誤解されたJavaScriptの "機能"の1つ。 'this'キーワード。 –

+0

優れた説明をありがとう! – wannabeartist

関連する問題