第一步是理解constructor
和prototype
都是關于。這并不難,但我們必須放棄古典意義上的“繼承”。
構造函數(shù)
這個constructor
財產(chǎn)不導致程序中的任何特殊效果,除非您可以查看它以查看與運算符一起使用的函數(shù)。new
來創(chuàng)建你的對象。如果你打字new Bar()
它將是Bar
你打字new Foo
它將是Foo
.
原型
這個prototype
屬性用于在所述對象沒有所請求的屬性的情況下進行查找。如果你寫x.attr
,JavaScript將試圖找到attr
在x
的屬性。如果它找不到它,它將查找x.__proto__
..如果它也不在那里,它就會往里面看x.__proto__.__proto__
等等只要__proto__
被定義。
所以什么是__proto__
它和這件事有什么關系prototype
?不久,prototype
代表“類型”__proto__
代表“實例”。(我這樣說是用引號表示的,因為類型和實例實際上沒有任何區(qū)別)。當你寫x = new MyType()
,發(fā)生的事情(除其他外)是x.__proto___
設置為MyType.prototype
.
問題
現(xiàn)在,您只需通過上面的內容來推導出您自己的示例的含義,而是嘗試回答您的實際問題;“為什么要寫類似的東西”:
Bar.prototype.constructor = Bar;
我個人從未見過它,我覺得它有點傻,但在你給出的上下文中,這意味著Bar.prototype
-對象(通過使用new Foo(42)
)將擺出已經(jīng)被創(chuàng)造出來的姿勢。Bar
而不是Foo
..我想這個想法是一些類似于C+/Java/C#的語言,其中類型查找(constructor
屬性)總是會產(chǎn)生最特定的類型,而不是原型鏈中更高的泛型對象的類型。
我的建議是:不要過多地考慮JavaScript中的“繼承”。接口和混合的概念更有意義。也不要檢查對象的類型。檢查所需的屬性(“如果它像鴨子一樣走路,像鴨子一樣嘎嘎叫,那就是鴨子”)。
試圖將JavaScript強制進入一個經(jīng)典的繼承模型,而它所擁有的只是上面描述的原型機制,這就是造成混亂的原因。建議手動設置constructor
-財產(chǎn)可能就是這樣做的。抽象是可以的,但是構造函數(shù)屬性的手動分配并不是JavaScript的慣用用法。