2012-08-22 6 views
5

私は次のコードを持っている:それは出力ですプロトタイプを変更しても、以前に作成されたオブジェクトに影響しないのはなぜですか?

var A = function() {}; 
var a = new A(); 
var b = new A(); 
A.prototype.member1 = 10; 

A.prototype = {} 
var c = new A(); 
console.log(a.member1); 
console.log(a.constructor === b.constructor); 
console.log(a.constructor === c.constructor); 
console.log('---------'); 
console.log(c.member1); 

は次のとおりです。

10 
true 
false 
--------- 
undefined 
undefined 

abのプロトタイプが変更されていないとcは新しいものを持っていました。これは、a.constructorc.constructorと等しくなく、それぞれがprototypeであるという事実によって引き起こされたのでしょうか? 2つのオブジェクトのコンストラクタが等しくない場合、他のサークルはありますか?

追加質問:なぜ2つの文字列が印刷されたのですか?undefined (クロム)時

+0

'a1'は' c'ですか? –

+0

申し訳ありませんが、私の間違い。修正済み;) –

+3

あなたはChromeにいますか?そうであれば、 'console.log(undefined)'はログに記録された 'undefined'と返された' undefined'の二つを記録します。 – pimvdb

答えて

5

あなたは基本的にこの割り当てが行われ

var a = new A(); 

呼んでいる:そうcそのよう{}を取得し、

a.__proto__ = A.prototype; 

は、その後、新しいオブジェクトに A.prototypeを再割り当てしますプロトタイプ。

A.prototype = {}; 
var c = new A(); 

しかし、これは古いA.prototypeオブジェクトを破壊しない - a.__proto__はまだそれを指しています。

これは、a.constructorがc.constructorと等しくなく、それぞれに独自のプロトタイプを持っていたために発生したと思いますか?

.constructorは基本的に単なる便利なプロパティです。インスタンスの振る舞いには影響しません。

余分な質問:なぜ2つの未定義の文字列が印刷されましたか?

私のコンソールにはありませんが、そうではありません! (Opera 12)

2

オブジェクトを作成すると、コンストラクタのプロトタイプが新しいオブジェクトの__proto__プロパティに割り当てられます。その後、プロトタイプを変更しているが、2つのabオブジェクトがすでに元の参照を指しています

var a = new A(); 
// a.__proto__ == A.prototype == {} (soon == {member1:10}) 
var b = new A(); 
// b.__proto__ == A.prototype == {} (soon == {member1:10}) 

A.prototype = {} // this changes A.prototype, but not a.__proto__ or b.__proto__ 
var c = new A(); // c.__proto__ = {} 

あなたの最初のundefinedc.member1からです。

A.prototype = {} 

あなたはこのコード行を取得

は、あなたが実際にBRAND NEWを作成する:第2回1は、クロムはあなたの全体の文が戻り値

1

答えはあなたのコード行にあるがなかったと言っています{}のメモリ内のOBJECT。 Aをコンストラクタとして使用して新しいオブジェクトを作成すると、このBRAND NEW OBJECTがプロトタイプとして指し示されます。

しかし、OLD PROTOTYPEはまだメモリに存在します。それだけです。プロトタイプはもはやそれを指していません。 Aのプロトタイプ参照を再定義する前にAをコンストラクタとして使用して作成したオブジェクトは、このOLD PROTOTYPEをプロトタイプとして引き続き指しています。