3

だから私は次のものを持っています:

function A () { this.a = 0; }
function B () { this.b = 0; }
function C () {}

C.prototype = new B();

var c1 = new C();
var c2 = new C();

c1.b = 10;

console.log(c1.b); // 10 
console.log(c2.b); // 0

http://jsfiddle.net/Mars6/2/

オブジェクトに変更B.bすると、 new ごとに同じオブジェクトが格納されているようですC:

function A () { this.a = 0; }
function B () { this.b = new A(); }
function C () {}

C.prototype = new B();

var c1 = new C();
var c2 = new C();

c1.b.a = 10;

console.log(c1.b.a); // 10 
console.log(c2.b.a); // 10 - I want this to be 0

http://jsfiddle.net/Mars6/1/

何が起こっているのか/何が問題なのか誰でも説明できますか?

4

2 に答える 2

6

あなたがしたとき

C.prototype = new B();

「プロトタイプが必要なときはいつでも」とは言いませんでしたnew B。あなたが言ったことは、「プロトタイプをに割り当てることですnew B()(これはそれほど驚くべきことではありません)。得られるものは次のとおりです。

C.prototype.b.a === 0

あなたがするときはいつでもnew C、あなたは複製していませんC.prototype-あなたはそれを同じBオブジェクトにリンクしているだけです:

C.prototype = new B()
   ^    ^
   |    |
  c1    c2

c1.b === c2.b; //true

ご存知かもしれませんが、オブジェクトは思いのままに変更できます。したがって、 を実行c1.b.a = 4すると、基礎となるオブジェクトにアクセスして、それをいじることになります。

編集:最初の例は、プロパティの解決がどのように機能するかによって機能します。プロパティが オブジェクトまたはにb存在しません。「give me」と言うと、js エンジンは次のように処理します。c1c2c1.b

  1. bにプロパティはありますc1か? いいえ、ありません。
  2. のプロトタイプを見てみましょうc1(実際のプロトタイプ、オブジェクトがメソッドとプロパティを取得したもの - この場合はC.prototype)
  3. ああ、それはbプロパティを持っています。返してください。

実際の js では、これ ( spec ) は次のとおりです。

function GetProperty (name, obj) {
    while (obj !== null) {
        if (obj.hasOwnProperty(name)) {
            return obj[name];
        }
        obj = Object.getPrototypeOf(obj);
    }
    return undefined;
}

つまり、それbがオブジェクトの場合、オブジェクトを保持しています。これを変更すると、通常のオブジェクトのように変更されます (c1.b直接割り当てているわけではないことに注意してください。私の言いたいことが少しわかります)。矢印で説明:

C.prototype.b = 0
   ^     ^
   |     |
  c1.b   c2.b

これは重要なので、もう一度強調します。 をつかむと、c1.b他のオブジェクトと同じように操作されるオブジェクトが得られます。それにプロパティを割り当てることは、他の通常のオブジェクトと同じです。

さて、前者のケース ( c1.b = 10) では、実際にプロパティを割り当てています。c1これは、オブジェクト自体でキーと値のペアを作成していることを意味します。したがって、最初のステップでc1は、 にプロパティがあるかどうかを確認しbます。より多くの矢印で説明:

      C.prototype.b = 0
            ^
            |
  c1.b=10  c2.b

後者の例を変更すると、同じ効果が観察できます。

//changing
c1.b.a = 10;
//to
c1.b = 4;

c2.b !== 4 && c2.b.a === 0; //true

要点をまとめると:

  • c1前の例では、オブジェクトにプロパティを設定するだけです。
  • 後者の例では、c1s プロトタイプのオブジェクトにプロパティを設定し、他のすべてのCオブジェクトでそれを変更しました。
于 2013-06-10T07:30:07.080 に答える
3

これが私が知る限り起こっていることです:

function A () { this.a = 0; }
function B () { this.b = 0; }
function C () {}

C.prototype = new B();

var c1 = new C();
var c2 = new C();

c1.b = 10;

記述するc1.b = 10と、JavaSript はbオブジェクトのローカル プロパティを追加または変更するだけc1です。プロトタイプがすでにプロパティbを持っていても、この場合はまったく影響を受けません。したがって:

console.log(c1.b); // 10  --> local property in c1
console.log(c2.b); // 0   --> prototype property

2番目の例では、何か違うことをしています。プロパティを に割り当てる代わりに、c1そのプロトタイプを操作して、すべてのインスタンスに影響を与えます。

c1.b.a = 10;

c1にはプロパティがないbため、プロトタイプ オブジェクトからそれを取得し、ITS プロパティを追加または変更しますa。現在、どちらc1c2ローカル プロパティを取得していないため、両方とも変更されたプロトタイプを参照しています。

console.log(c1.b.a); // 10  --> points to the prototype
console.log(c2.b.a); // 10 --> points to the prototype

考えられる解決策

c1.b = new A();
c1.b.a = 10
于 2013-06-10T07:50:29.720 に答える