3
function Entity() {
    this.a = {a: 4};
    this.b = 5;
}

function Thing() {}
Thing.prototype = new Entity;

var thing1 = new Thing;
thing1.a.a = 3;
thing1.b = 4;
var thing2 = new Thing;
console.log(thing2.a.a); // prints 3 instead of 4. I would like 4.
console.log(thing2.b) // prints 5 as wanted

javascriptでプロトタイプの継承を設定するのに問題があります。理想的には、thing1とthing2の両方に「新しいエンティティプロトタイプ」の独自のクリーンコピーを持たせたいと思います。

使用this.__proto__は避けたいものです

[編集]

私はこれがどのように機能するかについて大まかな考えを持っています。

things1.bを設定すると、Thingインスタンスのbプロパティが設定されます。これは、プロトタイプチェーンで定義されたEntity.bには触れません。

一方、Thingインスタンスにthing1.aaを設定すると、「未定義に設定できません」というエラーがスローされるため、実行できません。そのとき、プロトタイプチェーンを上って、定義されているEntity.aを見つけ、Entity.aaを新しい値に設定します。

[さらに編集]

@IvoWetzelが言うように、プロパティの設定はプロトタイプチェーンに影響を与えないため、thing1.bの設定はプロトタイプチェーンに影響を与えません。一方、thing1.aaの設定は2つのステップを実行します。プロトタイプチェーンに接触するthing1.aのゲッターと、それに続く.aのセッター

4

3 に答える 3

6

できることは、コンストラクターのロジックを内部に適用することです。次に例を示します。EntityThing

function Entity() {
    this.a = {a: 4};
    this.b = 5;
}
Entity.prototype.c = 6;

function Thing() {
  Entity.apply(this, arguments); // ejecutes the assignments made in Entity
}
Thing.prototype = new Entity;

var a = new Thing;
a.a.a = 3;

var b = new Thing;
console.log(a.a.a); // 3
console.log(b.a.a); // 4

console.log(a.b);   // 5
console.log(b.b);   // 5

console.log(a.c);   // 6
console.log(b.c);   // 6
于 2010-11-24T00:10:41.757 に答える
2

CMS は解決策を投稿しましたが、なぜthing2.b5 を返しthing2.a.a、オブジェクトに解決されるのですか?

var thing1 = new Thing;

// thing1 has no a, but the prototype has so a.a is essentially the a of Entity
thing1.a.a = 3;

// Sets b on thing1, setting does not go up the prototype chain(!)
thing1.b = 4;  

// that's what thing1 looks like
Thing {proto: Entity { 
                      a: { <--- gets resolved 
                          a: 3 <-- gets set
                      }, 
                      b: 5
              },
              b: 4 <-- gets set directly
      }


var thing2 = new Thing;

// thing2.a does not exist, so we look up the prototype and find a on Entity
console.log(thing2.a.a); 

// thing2.b also does not exists, so once again we look up the prototype to find b on Entity
console.log(thing2.b);

// that's what thing2 looks like
Thing {proto: Entity {
                      a: {
                          a: 3 <- gets resolved
                      },
                      b: 5 <- gets resolved
              }
      }

すべての問題は、JavaScript がプロパティを見つけるためにプロトタイプ チェーンを上っていくことにあります。ただし、プロパティを設定すると、チェーンは上がりません。

于 2010-11-24T00:21:26.600 に答える
0

これは、JavaScript オブジェクトが常に参照として扱われるためです。

したがって、実行してthis.aオブジェクトを変更a.a.a = 3;すると、メモリ内のその 1 つのオブジェクトが変更されます。の新しいインスタンスは、毎回コンストラクターが呼び出されるわけではなく、オブジェクトが同じままであるThingため、メモリ内の同じオブジェクトを参照します。EntityThingthis.a

this.aプロトタイプ チェーンの外側、おそらく直接Thingコンストラクターの内側に配置します。これにより、がインスタンス化this.aされるたびに の新しいバージョンがメモリ内に作成されるようになります。Thing

于 2010-11-24T00:13:25.050 に答える