3

簡単な説明:関数宣言、新しいキーワード、およびプロトタイプアプローチ(以下の例)でOOJavascriptを使用しています。オブジェクトの各メソッド内で「自己」オブジェクトを参照する方法が必要です。「this」は、メソッドを直接呼び出している場合にのみ機能するようです。それ以外の場合、「this」は、代わ​​りにメソッドを呼び出したものを参照しているようです。

詳細:これが私のオブジェクトの簡略化されたバージョンです。

function Peer(id) {
    this.id = id;
    this.pc = new RTCPeerConnection(SERVER);

    this.pc.onevent1 = this.onEvent1;
    this.pc.onevent2 = this.onEvent2;
}

Peer.prototype.doSomething = function() {
    // create offer takes one param, a callback function
    this.pc.createOffer(this.myCallback);
};

Peer.prototype.onEvent1 = function(evt) {
    // here this refers to the RTCPeerConnection object, so this doesn't work
    this.initSomething(evt.data);    
};

Peer.prototype.myCallback = function(data) {
    // here this refers to the window object, so this doesn't work
    this.setSomething = data;
};

Peer.prototype.initSomething = function(data) {
    // use data
};

そして、これがその使用例です。

var peer = new Peer(1);
peer.doSomething();
// eventually something triggers event1

コードをできるだけ単純化し、コメントで問題を説明しようとしました。これのローカルコピーを作成し、このローカルコピーを使用して必要な関数を呼び出す匿名関数をコールバックパラメーターにすることで、最初のシナリオ(this.myCallbackを呼び出す)の回避策を作成しました。しかし、2番目のシナリオはもっと厄介です(イベントの発生)。

メソッドがどのように呼び出されたかに関係なく、すべてのメソッドが常に親オブジェクトへの適切な参照を持つオブジェクト指向プログラミングの異なるモデルがあるかどうか興味がありましたか?または、カスタムオブジェクトのプロパティとしてオブジェクトを作成し、そのイベントをカスタムオブジェクトのメソッドにバインドする別の方法がある場合はどうでしょうか。これが紛らわしい言葉ならごめんなさい!私の質問はRTCPeerConnectionとは何の関係もないことに注意してください。それは、たまたま私が現在取り組んでいるプロジェクトでした。

私はこの記事を見つけました:http://www.alistapart.com/articles/getoutbindingsituationsしかし、私はこの情報をどのように使用するか完全に確信していませんでしたか?

4

2 に答える 2

6

メソッドがどのように呼び出されたかに関係なく、すべてのメソッドが常に親オブジェクトへの適切な参照を持つオブジェクト指向プログラミングの別のモデルがあるかどうか、私は興味がありましたか?

はい、ありFunction.bindます。

function Peer(id) {
    this.id = id;
    this.pc = new RTCPeerConnection(SERVER);

    this.pc.onevent1 = this.onEvent1.bind(this);
    this.pc.onevent2 = this.onEvent2.bind(this);
}

同様に、が常にインスタンスを参照するには、次myCallbackのようにします。thisPeer

Peer.prototype.doSomething = function() {
    // create offer takes one param, a callback function
    this.pc.createOffer(this.myCallback.bind(this));
};
于 2013-01-11T16:39:42.217 に答える
1

メソッドは、プロトタイプのプロパティとして定義された単なる関数です。それ自体には特定のオブジェクトコンテキストはありません。これは、特定のタイプのオブジェクトが無限に存在する可能性があるため、特定のオブジェクトのコンテキストが与えられたときにメソッドが機能するためです。

JavaScript (および他の OO 言語も) では、そのオブジェクト コンテキストは呼び出し元によって提供されます。これを行う古典的な方法は、特定のオブジェクトでメソッドを呼び出す場所です。

obj.method();

ただし、またはまたはthisを使用して、ポインターを別のものに設定することもできます。MDN でそれらすべてについて読むことができます。 一部の古いブラウザーではサポートされていないため、shim を使用するか、別のソリューションを使用する必要があります (私は以下で説明するものを使用します)。.apply().call().bind().bind()

thisしたがって、呼び出し元は、 ptr が適切に設定されていることを確認する責任を負う必要があります。それがJavaScriptの仕組みです。

メソッド呼び出しをコールバックとして渡そうとするときの別の設計パターンの回避策は次のとおりです。

var self = this;
callMeWhenDone(function() {
    self.myMethod();
});

ここでは、ptr をローカル変数に保存し、thisそれを使用して匿名コールバックからメソッドを呼び出します。これthisは、コールバック内のポインターが別のものに設定されるためです。

注: 内部的に.bind()は、この回避策と同様のことを行っているだけです。

于 2013-01-11T16:56:55.237 に答える