2011-10-28 156 views
1

比方說,我有一個構造函數:什麼時候在JavaScript中誕生的原型對象?

function Cat() 
{ 
    this.tail = "long"; 
    this.colour = "black"; 
} 

console.log(Cat.prototype); 
// returns an empty [object Object] with no properties (checked with `for...in` loop). 

因此,似乎在這一點上Cat.prototype沒有tailcolour

var Charlie = new Cat(); 
console.log(Charlie.tail); 

那麼,如何Charlie繼承,如果他們沒有在其原型定義的Cat屬性。我假設原型對象的整個觀點是鏡像或存儲構造函數的屬性,它將被所有cat實例繼承 - 這是錯誤的嗎?

原型Object在什麼時候被這些屬性填滿?或者僅當我明確設置Cat.prototype.eyes = brown爲例時纔會發生這種情況?

此外,查詢對象原型的屬性的正確方法是什麼?這是一個for...in循環嗎?我想它不能是Object.getOwnPropertyNames(Cat.prototype),因爲那不會返回繼承的屬性。

+0

在你需要把方法(函數)的原型,而不是字符串屬性... –

+0

是的,你可以做'Object.getOwnPropertyNames(貓。原型)',這沒什麼錯。 –

回答

1

prototypethis完全分開。

this中的所有東西都不會被繼承,prototype中的東西會。 默認情況下,您從Object.prototype繼承(裏面是空的)

function Cat() 
{ 
    this.tail = "long"; 
    this.colour = "black"; 
} 
Cat.prototype.getColour = function() { 
    return this.colour; 
} 

WhiteCat.prototype = Cat.prototype; 
WhiteCat.prototype.constructor = WhiteCat; 

function WhiteCat(name){ 
    Cat.call(this); 
    this.colour = "white"; 
}  

var c = new Cat(); 
console.log(c.getColour()); // "black" 
var w = new WhiteCat(); 
console.log(w.getColour()); // "white" 
+0

這是不正確的 - 'this'值代表'Cat'實例,它沒有'prototype'屬性。只有函數(如本例中的Cat)具有'prototype'屬性。 –

+0

啊,對。修復。我發現原型非常麻煩。如果你熱衷於面向對象,我建議你使用一些框架爲你做繼承。 – Halcyon

+0

這並不壞,你已經習慣了。但是,我不確定'WhiteCat.prototype = Cat.prototype;'是個好主意。您通常希望擁有單獨的原型,以便您可以定義特定於某個「類」(本例中爲「WhiteCat」)的方法。 –

2

您直接在實例定義tailcolour性能。這些屬性未在prototype對象上定義。

順便說一句,每個函數都有一個prototype屬性,它是在創建函數本身時創建的。

0

原型將永遠不會獲得您放入對象中的屬性。該對象具有原型的成員,但原型沒有該對象的成員。

對象沒有從原型繼承任何東西,原型中的成員仍然只存在於原型中,它們只能從對象中訪問。如果在創建對象後從原型中刪除某些內容,則該對象也不再可以從對象訪問。

函數具有prototype屬性,並且當您使用new關鍵字將該函數作爲構造函數調用時,創建的對象將從該函數獲取原型。

如果你添加了一些功能的雛形,這也將是通過使用該功能創建的對象訪問,即使你創造了他們將其添加到原型之前:

function Cat() {} 

var c = new Cat(); 

Cat.prototype.test = function() { 
    alert('test'); 
}; 

c.test(); // alerts 'test' 
0

而且,查詢對象原型的屬性的正確方法是什麼?

var myProto = Object.getPrototypeOf(someObject); 
var names = Object.getOwnPropertyNames(myProto); 
names.forEach(function (name) { 
    value = myProto[name]; 
    ... 
}); 

抑或這時候我明確設置Cat.prototype.eyes =棕色僅僅作爲示例來發生的呢?

是的,只有手動設置對象時,纔會設置對象的屬性[[Prototype]]

但每一個原型的「實例」有活的指針原型對象,該對象被創建後,這些變化將反映。

存儲將由所有貓的實例繼承的構造函數的屬性 - 這是錯誤的?

我們不保存在原型對象的屬性。我們存儲我們想要在原型/構造函數的所有實例之間共享的屬性(主要是方法)。

1

原型在Javascript比你所描述的有所不同。在這種情況下Charlie確實有尾巴,因爲Charie是阿Cat也就是說,他是Cat Cat類的實例。在你Cat功能添加尾屬性與this.tail =線所有的貓。這完全是因爲您使用new關鍵字調用了函數Cat。當你這樣做時,javascript會創建一個新對象,然後在該函數的上下文中使this指向該對象。

現在原型工作方式不同,他們是最好被視爲如果你去尋找一個特性或功能是不存在的對象之後,將鏈。例如,如果嘗試去:

Charlie.tickle_wiskers(); 

的Javascript會去尋找一個在查理對象調用tickle_wiskers功能。如果它沒有找到該功能,它將查看Charlies原型(如果沒有明確設置,默認爲Object.prototype)。最後,我可以給所有的貓是由功能會是這樣的:

Cat.prototype.tickle_wiskers = function() { 
     alert('meow'); 
    } 
+0

考慮不要用對象字面值覆蓋'Cat.prototype'。這破壞了Cat.prototype.constructor === Cat'關係。這是通過'Cat.prototype.tickle = ...' –

+0

添加方法的好方法。我根據你的建議進行了編輯 – Matthew

相關問題