1

Object.prototype からのものであっても、すべての JavaScript オブジェクトにはプロトタイプがあることを理解していました。

サーバーから参加者データを取得するasp.net Webサービスプロキシがあります。その部分はうまく機能します。コードは次のとおりです。

        atomWebServiceProxy.GetInteractionParticipants(interactionId,
            function (participantsResult) {
                var assetId, pendingPathFetches;
                participants = participantsResult;
                pendingPathFetches = participants.length;
                document.title = participants.length + " participants:";
                for (var i = 0; i < participants.length; i++) {
                    assetId = participants[i].ASSETID;
                    document.title += " " + participants[i].DISPLAYID;
                    atomWebServiceProxy.GetInteractionPath(interactionId, assetId,
                        function (pathResult, participant) {
                            participant.path = pathResult;
                            pathResult.participant = participant;
                            if (--pendingPathFetches == 0) {
                                setTimeout(afterInit, 20);
                            }
                        },
                        function (error, participant) {
                            alert(participant.DISPLAYID + " reported this error: " + error.get_message());
                        },
                        participants[i]
                    );
                }
            },
            function (error) {
                alert(error.toString());
            });

ネストされた呼び出しがあることに気付くかもしれません。各参加者オブジェクトにパス プロパティを追加し、オブジェクト モデルで、それがその特定の参加者のパス データであるという事実を表現しています。これもうまくいきます。

次に、次のようにプロトタイプにメソッドを追加しようとしました。

var foo = participants[0];
foo.prototype.redraw = function(map) {
   ... //code that redraws
};

驚いたことに、prototype が null であると主張する例外が発生しました。

JavaScript ランタイム エラー: 未定義または null 参照のプロパティ 'redraw' を設定できません

ここで何が起こっているのですか?

この質問は問題に対処しているようですが、コードで定義されていないコンストラクターを参照する方法がわからないため、この情報をこの状況に適用する方法がわかりません。

これが有用な情報である場合、実行時の即時ウィンドウでのparticipants.constructorの検査は、コンストラクターがArray()であったことを示しているように見えます

フィールドをオブジェクトにコピーしてプロトタイプを設定するコンストラクタを作成する必要がありますか? もしそうなら、C# リフレクションに相当する JavaScript があるので、クエリ結果オブジェクトのすべてのタイプに対してこれを書き直す必要はありませんか? 注comaは、質問を更新しているときに、コメントで質問のこの部分に答えました。

4

2 に答える 2

4

この特定のケースでは、関数をプロトタイプに追加しようとするのではなく、オブジェクト自体に関数を追加する方がよいでしょう。

しかし、「コンストラクターの名前がわからない場合、どうすればプロトタイプを設定できますか?」という質問に答えるには、:

既存のオブジェクトのプロトタイプを設定することはできません(標準的な方法ではありません)。プロトタイプは構築時に割り当てられ、(標準的な方法で) 変更することはできません。オブジェクトのプロトタイプのプロパティは変更できますが、そのプロトタイプであるオブジェクトは変更できません。

オブジェクトのプロトタイプは、 という名前のプロパティからは利用できませんprototypeprototypeプロパティは関数に関連していますnewこれは、 expessionを使用してその関数を介して作成されたオブジェクトのプロトタイプとして割り当てられるオブジェクトです(たとえば、新しく作成されたオブジェクトのプロトタイプとしてnew Foo()割り当てFoo.prototypeます)。

経由で ES5 のオブジェクトのプロトタイプを取得できますObject.getPrototypeOf。一部の ES5 より前の実装では、非標準__proto__プロパティを介して利用できます。(そして、これらの実装の一部では、書き込みが可能です。そのため、標準的な__proto__方法でプロトタイプ オブジェクトを交換できないと言ったのです。それをサポートする実装では、非標準的な方法で交換できます。)

したがって、ES5 環境では、次のようにオブジェクトのプロトタイプを拡張できます。

Object.getPrototypeOf(theObject).newstuff = "foo";

ただし、それによってプロトタイプが変更され、他のオブジェクトがそれを使用している可能性があることに注意してください。例えば:

// A constructor function, and a prototype to assign to objects created with it
function Foo() {
}
Foo.prototype.hi = function() {
    console.log("Hi");
};

// Create two objects
var f1 = new Foo();
var f2 = new Foo();

// Add something to the prototype of `f1`:
Object.getPrototypeOf(f1).there = function() {
    console.log("there");
};

// Since `f1` and `f2` *share* the same prototype object,
// `f2` now has it too!
f2.there(); // "there"

ライブコピー| ソース

于 2013-05-06T08:41:01.727 に答える
1

コンストラクターの代わりにメソッドをオブジェクトに追加するには、プロトタイプを介する代わりに直接追加するだけです。

var foo = participants[0];
foo.redraw = function(map) {
   ... //code that redraws
};
于 2013-05-06T08:40:55.830 に答える