理解原型對(duì)象
- prototype
只要?jiǎng)?chuàng)建一個(gè)新函數(shù),就會(huì)根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象。 - 原型對(duì)象
原型對(duì)象包含可以由(自定義的引用類型對(duì)象的所有實(shí)例對(duì)象)共享的屬性和方法。 - constructor
在默認(rèn)情況下,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè)constructor屬性,這個(gè)屬性是一個(gè)指向prototype屬性所在函數(shù)的指針。 - [[prototype]]
- 當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例后,該實(shí)例的內(nèi)部將包含一個(gè)指針(內(nèi)部屬性),指向構(gòu)造函數(shù)的原型對(duì)象。
- [[prototype]]存在于實(shí)例和構(gòu)造函數(shù)的原型對(duì)象之間。

關(guān)系圖-1
isPrototypeOf()
如果調(diào)用isPrototypeOf()方法的對(duì)象就是[[prototype]]指向的對(duì)象,這個(gè)方法就返回true。Object.getPrototypeOf()
返回[[prototype]]的值。當(dāng)為對(duì)象實(shí)例添加一個(gè)屬性時(shí),這個(gè)屬性就會(huì)屏蔽原型對(duì)象中保存的同名屬性。
hasOwnProperty()
如果屬性存在于實(shí)例中,返回true
原型與in操作符
- 單獨(dú)使用
無論屬性存在于實(shí)例中還是原型中,in操作符通過對(duì)象能夠訪問到該屬性,返回true。 - for-in循環(huán)中使用
返回所有- 能通過對(duì)象訪問的
- 可枚舉的(enumberated)屬性,其中既包括存在于實(shí)例中的屬性,也包括存在于原型中的屬性。
- 屏蔽了原型中不可枚舉屬性的實(shí)例屬性,因?yàn)樗虚_發(fā)人員定義的屬性都是可枚舉的。
- Object.keys()
接收一個(gè)對(duì)象作為參數(shù),返回一個(gè)包含所有可枚舉屬性的字符串?dāng)?shù)組。 - Object.getOwnPropertyNames()
返回所有實(shí)例屬性。
更簡單的原型語法
為減少不必要的輸入,也為了從視覺上更好的封裝原型的功能,用一個(gè)包含所有屬性和方法的對(duì)象字面量來重寫整個(gè)原型對(duì)象。
- 弊端
將導(dǎo)致constructor不再指向構(gòu)造函數(shù),而是指向了Object
使用Object.defineProperty()重設(shè)構(gòu)造函數(shù),只適用于ECMAScript 5兼容的瀏覽器。
原型的動(dòng)態(tài)性
對(duì)原型對(duì)象所做的任何修改都能夠立即從實(shí)例上反映出來,即時(shí)先創(chuàng)建了實(shí)例后修改原型也如此。
- 原因:
實(shí)例與原型之間的松散連接關(guān)系。實(shí)例和原型對(duì)象之間的連接是指針,而非副本,通過指針在原型中搜索。 - 缺陷:
重寫整個(gè)原型對(duì)象,相當(dāng)于給構(gòu)造函數(shù)的的prototype指針指向了另一個(gè)原型對(duì)象。

關(guān)系圖-2
原生對(duì)象的原型
除了自定義類型之外,原生的引用類型(Object、Array、String,等等)都在其構(gòu)造函數(shù)的原型上定義了方法。
不建議在產(chǎn)品化的程序中修改原生對(duì)象的原型??赡苤貙憽?/p>
原型對(duì)象的問題
- 省略了為構(gòu)造函數(shù)傳遞初始化參數(shù),結(jié)果所有實(shí)例在默認(rèn)情況下都將取得相同的屬性值。
- 對(duì)于包含引用類型值的屬性,在一個(gè)實(shí)例中添加同名屬性,無法屏蔽原型中的屬性值,而是直接修改了。