4

オブジェクトリテラルのみを使用したいとします(コンストラクターではありません)。私はこのようなオブジェクトを持っています:

var o = {
  name : "Jack"
}

プロトタイプである別のオブジェクトを作成する場合は、次のo構文を使用します。

var u = Object.create( o );
console.log( u.name );//prints Jack
u.name = "Jill";
console.log( u.name );//prints Jill

正常に動作します!問題ない。しかし、実行時に、のプロトタイプを別のものに変更したいと思いuます。u次のようなコンストラクターで作成された場合:

function U () {}
U.prototype.name = "Jack";
var u = new U;
console.log( u.name );//prints Jack

また

function U () {
  this.name = "Jack";
}
var u = new U;
console.log( u.name );//prints Jack

しかし、コンストラクターを使用する場合、プロトタイプを完全に変更できます

function U () {}
//totally changed the prototype object to another object
U.prototype = {
  dad : "Adam"
}
var u = new U;
console.log( u.dad );//prints Adam

次に、のプロトタイプに追加したUものはすべて、それらの変更後に作成されるすべてのオブジェクトに自動的に追加されます。しかし、オブジェクトリテラルで同じ効果を得るにはどうすればよいですか?

クリーンで短い構文を持つ最も単純なソリューションを提供してください。これを手動で行うことが可能かどうかを知りたいだけです。__proto__非標準のキーワードも使いたくない。

Stackoverflowを検索しましたが、これは実際には次の質問と重複していません。

(可能であれば)標準的な方法で作成後にプロトタイプを変更したいからです。のようなものObject.setPrototype()は完璧ですが、その機能は存在しません!オブジェクトリテラルの初期化を使用して作成されたオブジェクトのプロトタイプを簡単に設定する他の方法はありますか?

4

1 に答える 1

6

現在の仕様では、インスタンス化されたオブジェクトのプロトタイプを変更することはできません(たとえば、あるオブジェクトをスワップアウトし、別のオブジェクトをスワップインします)。(ただし、以下を参照してください。状況が変化している可能性があります。)変更できるのはオブジェクトのプロトタイプのみです。しかし、あなたの質問を見ると、それがあなたが望むすべてかもしれません。

区別を明確にするために:

var p1 = {
    foo1: function() {
        console.log("foo1");
    }
};
var p2 = {
    foo2: function() {
        console.log("foo1");
    }
};

var o = Object.create(p1);
o.foo1(); // logs "foo1"
o.foo2(); // ReferenceError, there is no foo2
// You cannot now *change* o's prototype to p2.
// You can modify p1:
p1.bar1 = function() { console.log("bar1"); };
// ...and those modifications show up on any objects using p1
// as their prototype:
o.bar1(); // logs "bar1"
// ...but you can't swap p1 out entirely and replace it with p2.

質問に戻ります:

uがこのようなコンストラクターで作成された場合...のプロトタイプに追加したUものはすべて、それらの変更後に作成されるすべてのオブジェクトに自動的に追加されます。しかし、オブジェクトリテラルで同じ効果を得るにはどうすればよいですか?

Object.create上記のように、プロトタイプとして渡したオブジェクトを変更します。追加する前に作成されたにもかかわらず、に追加bar1すると、p1で利用できるようになったことに注意してください。コンストラクター関数の場合と同様に、プロトタイプの関係は永続的であり、作成時のスナップショットを取得せず、永続的なリンクを取得します。ooop1


ES.nextは、「setプロトタイプ演算子」(<|)を持っている可能性が高いように見えます。これにより、それが可能になります。しかし、現在、そのための標準的なメカニズムはありません。一部のエンジンは、この機能を提供するという疑似プロパティを実装して__proto__いますが、標準化されていません。

于 2012-11-05T15:37:06.750 に答える