2012-08-22 41 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.constructor不等於c.constructor,並且他們每個人都有自己的prototype?當兩個對象的構造函數可能不相等時,還有其他方法嗎?

額外的問題:爲什麼會打印兩個undefined字符串? (鉻)

+0

'a1'應該是'c'嗎? –

+0

對不起,我的錯。更正;) –

+3

你在鉻?如果是這樣,'console.log(undefined)'會記錄兩件事:記錄的undefined和返回的undefined。 – pimvdb

回答

5

當時你打電話

var a = new A(); 

基本上這個任務完成:

a.__proto__ = A.prototype; 

然後你重新分配A.prototype到一個新的對象,所以c得到{}爲原型。

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

然而,這並沒有破壞舊A.prototype對象 - a.__proto__仍然指向它。

我是對的,這是由於a.constructor不等於c.constructor,他們每個人都有自己的原型的事實?

.constructor基本上只是一個便利的屬性。它對實例的行爲沒有影響。

額外的問題:爲什麼會打印兩個未定義的字符串?

不在我的控制檯,他們不! (Opera 12)

2

當您創建一個對象時,構造函數的原型被分配給新對象的__proto__屬性。那麼你就改變了原型,但兩個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。第二屆一個是鉻說你的整個語句沒有返回值

1

問題就出在這行代碼的:

A.prototype = {} 

當你到了這行代碼,您實際上是創建一個全新的內存中的對象是{}。使用A作爲構造函數創建任何新對象將指向此品牌新對象作爲原型。

但是,OLD PROTOTYPE仍然存在於內存中。這只是A.原型不再指向它。在重新定義A的原型參考之前,使用A作爲構造函數創建的任何對象仍然指向這個OLD PROTOTYPE,因爲它是原型。

相關問題