2

クイックノート:あなたの答えの中でjavascriptの継承の基本を説明しないでください。

これは、プロトタイプメンバーにいくつかのプロパティが付加された単純なコンストラクター関数です。

function Foo() { 
    this.relationship = "Love"; 
};

Foo.prototype.name = "Natalie";
Foo.prototype.age = 22;
Foo.prototype.country = "France";

次に、Fooを使用して新しいオブジェクトを作成し、いくつかの基本をテストします。すべてがかっこいいです。

var girl = new Foo();

girl.hasOwnProperty("relationship"); //=> true
girl.hasOwnProperty("name");         //=> false

girl.relationship;  //=> "Love"
girl.name;          //=> "Natalie", this comes from Foo.prototype

girl.__proto__ === Foo.prototype;            //=> true
girl.__proto__.name === Foo.prototype.name;  //=> true
girl.name === Foo.prototype.name;            //=> true

また、Foo.prototype.nameプロパティの値を更新すると、girl.nameは新しい値を指すようになります。

Foo.prototype.name = "Lucia";
girl.name;  //=> "Lucia", this comes from Foo.prototype


Foo.prototypeを変更して、null、未定義、空のオブジェクトなどにすると、不思議なことが起こります。

Foo.prototype = null;

女の子のオブジェクトにFoo.prototypeへの非表示(ECMA [[Prototype]])リンクがある場合__ proto__、Foo.prototypeをnullにした後、女の子がnameプロパティを取得する可能性はありませんが、取得できます。

girl.name;     //=> "Lucia"
girl.age;      //=> 22
girl.country;  //=> "France"

ここで、この時点でFooを使用して別のオブジェクトを作成するとします。もちろん、Foo.prototypeはnullであるため、名前年齢はありません。

var new_girl = new Foo();
new_girl.name;     //=> undefined
new_girl.age;      //=> undefined
new_girl.country;  //=> undefined


だから私の質問は、Foo.prototypeをnullに割り当てた後、地球上で前のオブジェクト(女の子)と彼の隠されたリンクがそれらのプロパティをどのように記憶できるかということです。__ proto__

4

1 に答える 1

2

それはまったく神秘的ではなく、継承とは何の関係もありません。
オブジェクトポインター/参照に関係しています。

var a = { name : "Bob", age : 32 };
var b = a;

b.name; // "Bob";
a.name = "Jim";
b.name; // "Jim";
a = null;
b.name; // "Jim";

どうしたの?

ab同じオブジェクトへのポインタが与えられました。どちらか一方を参照して object のプロパティを
変更すると ( onまたは on で変更しても問題ありません)、もう一方の参照にも変更が反映されます。 ab

同じプロパティと値を持つ新しいオブジェクトを作成するのではなく、同じオブジェクトのアドレスを両方に与えるだけで、尋ねるたびにプロパティを検索します。

次に、 を再割り当てしaます。

オブジェクトを変更しているのではなく、a別の場所にアドレスを指定しています。
b住所はまだです。

したがって、次のように考えてください。

function Foo () { }
Foo.prototype = { name : "Bob", age : 32 };

var a = new Foo();
var b = new Foo();

a.__proto__ === Foo.prototype;
b.__proto__ === Foo.prototype;

Foo.prototype.age = 35;

a.age; // 35
b.age; // 35

// now we're replacing the `.prototype` reference with a brand new object
Foo.prototype = { name : "Sally", age : 16 };

a.__proto__ !== Foo.prototype;
b.__proto__ !== Foo.prototype;

a.name; // "Bob"
b.age;  // 35

コンストラクターがバックグラウンドで行っていることはすべて、次のように言っています。

this.constructor = arguments.callee;
this.__proto__   = this.constructor.prototype;

したがって、両方が参照するオブジェクトのプロパティを変更し、どちらかthis.constructor.prototypethis.__proto__検索すると、新しい値が見つかります。
ただし、一方から参照を削除しても、他方のオブジェクトは削除されません。

それがあなたが望む結果である場合は、プロトタイプの各プロパティを消去する必要があります (関数またはインスタンスのいずれかからそれを行う場所は関係ありません) .prototype。空のオブジェクト (null を使用すると、ブラウザが少ない場合はエラーが発生します)、将来のオブジェクトはアクセスできません。

于 2013-02-17T20:54:06.010 に答える