2010-07-28 100 views
8

我很努力地理解以下兩組代碼的區別。原始代碼是the famous Ninja tutorial,我已經簡化了一下。JavaScript:通過原型分配屬性

問題:我想我理解CodeA是如何工作的。 Ninja.prototype.swung = false正在將一個新屬性分配到function Ninja(),並且因此ninjiaA.swung評估爲false。但是,在CodeB中,當我們在開始時聲明function Ninja()this.swung = true時,後面的Ninja.prototype.swung = false分配不起作用,並且ninjaA.swung仍然需要評估爲true。我不明白爲什麼後面的作業在CodeB中不起作用。請問有人可以在這方面給我啓發嗎?

CODEa所:

function Ninja(){} 
Ninja.prototype.swung = false; 
var ninjaA = new Ninja(); 
ninjaA.swung; //evaluates to false 

CodeB:

function Ninja(){ 
    this.swung = true; 
} 
Ninja.prototype.swung = false; //I'm expecting this changes swung to false, 
           //but it doesn't. 
var ninjaA = new Ninja();  
ninjaA.swung; //evaluates to true 

非常感謝提前。

回答

15

當您在構造函數中使用this聲明屬性時,它將被附加到該構造函數的每個對象。

當你在該構造函數的原型上聲明一個屬性時,它仍然存在,並且該構造函數的所有對象都引用它。當對象和原型鏈中有同名的屬性時,該對象的屬性將隱藏原型上的屬性。

想想如何在原型鏈中評估屬性,這可能會使事情變得更加清晰。

CODEa所:

 
ninjaA.swung 

1. Is swung a property of the current object - No 
2. Is swung a property of the current object's prototype - Yes 
    2.1. Return it 

CodeB:

 
ninjaA.swung 

1. Is swung a property of the current object? - Yes 
    1.1 Return it 

在代碼B,它永遠不會對樣機的性能。

+2

+1 - 很好地佈局! – 2010-07-28 00:23:38

+0

我編輯了你的答案以使用'pre'標籤。我發現幾乎幽默的色彩會降低答案的質量。 – ChaosPandion 2010-07-28 00:38:16

+0

@丹 - 謝謝:) @ChaosPandion - 感謝您的改變,現在看起來好多了:) – Anurag 2010-07-28 00:40:00

6

當呼叫Ninja作爲構造函數時,您將值true指定爲swung。在執行構造函數之前的對象將是這樣的:

{ 
    prototype : { 
     swung : false 
    } 
} 

執行構造函數後:

{ 
    prototype : { 
     swung : false 
    }, 
    swung : true 
} 

當你問物業swung原型鏈將在各個層面進行檢查,看如果存在。如果不存在,則將返回值undefined

+1

+1您的新增內容對於發生了什麼非常明確。 – Anurag 2010-07-28 00:41:26

+1

@Anurag - 謝謝,我認爲你一步一步解釋它會幫助新手更好地理解它。 – ChaosPandion 2010-07-28 00:49:15

3

在JavaScript中,只有在實例中未找到方法時纔會調用附加到原型的方法。