不啰嗦氯葬,畫圖有個(gè)直觀的印象挡篓。
吐槽:眾說紛紜。
寫幾個(gè)要點(diǎn):
prototype屬性是構(gòu)造函數(shù)才有的帚称。
[[Prototype]]屬性是所有對(duì)象都有的官研。(構(gòu)造函數(shù)是Function的實(shí)例對(duì)象)
constructor屬性是原型對(duì)象才有的。(這個(gè)真說法不同闯睹,以紅寶書為準(zhǔn)戏羽,chrome打印也印證了)
__proto__是定義在原型對(duì)象上的訪問器屬性!(需要提前知道構(gòu)造器屬性)
原型是一種對(duì)象和對(duì)象之間的關(guān)系楼吃,如A對(duì)象是B對(duì)象的原型始花。
字面量生成的對(duì)象,如let a={}孩锡,a的[[prototype]]指向Object相關(guān)的原型對(duì)象酷宵。經(jīng)常的,我們通過:類名.prototype={ ... } 生成的原型對(duì)象屬于字面量定義形式躬窜。
一浇垦、圖解原型,原型鏈和__proto__
如圖1荣挨,__proto__屬性實(shí)際上是定義在原型對(duì)象上的構(gòu)造器屬性男韧,當(dāng)調(diào)用 x_obj.__proto__ 時(shí),實(shí)際調(diào)用的是它原型對(duì)象的訪問器屬性__proto__中的get方法默垄,再通過規(guī)范調(diào)用Object.getPrototypeOf(this)返回 x_obj 的原型對(duì)象此虑。
最后Object相關(guān)的原型對(duì)象的[[prototype]]指向NULL,作為原型鏈的終止口锭。
綠色的箭頭組成的就是原型鏈寡壮。
自己敲代碼打印證明一下:
利用Object.definePrototype()方法在Person.prototype指向的原型對(duì)象中定義__proto__屬性(將原型對(duì)象中原有的__proto__屬性覆蓋),然后通過實(shí)例對(duì)象 p 調(diào)用__proto__屬性,可以根據(jù)打印出來的結(jié)果確定:實(shí)例對(duì)象所調(diào)用的__proto__是定義在原型對(duì)象上的况既。
二这溅、利用原型實(shí)現(xiàn)繼承
先看兩個(gè)類的圖示:老朋友 X 和新來的 A1、讓X的prototype指向一個(gè)A的實(shí)例對(duì)象
X.prototype = new A();
X.prototype.constructor = X;
對(duì)比圖三可以看到棒仍,通過構(gòu)造函數(shù)A new 出來的實(shí)例對(duì)象 a_obj 的原型的constructor屬性是指向A的構(gòu)造函數(shù)的(這句話好繞悲靴,但是看圖就很清楚)。
所以圖四中莫其,若將A的一個(gè)實(shí)例對(duì)象 a_obj 作為 X構(gòu)造的實(shí)例對(duì)象的原型癞尚,必須在 a_obj 對(duì)象中添加一個(gè) constructor屬性,讓它指向 X 構(gòu)造函數(shù)乱陡,以覆蓋 a_obj 的原型中的constructor浇揩。找一個(gè)屬性會(huì)先查找該對(duì)象本身,找不到才會(huì)順著原型鏈去找憨颠, x_obj 的原型鏈包括A實(shí)例對(duì)象的原型胳徽,也就實(shí)現(xiàn)了繼承。(看圖的綠色線路)
2爽彤、讓X的prototype指向一個(gè)A相關(guān)的原型對(duì)象
X.prototype = A.prototype;
其實(shí)就是所有X的實(shí)例對(duì)象养盗,所有A的實(shí)例對(duì)象,共享一個(gè)原型對(duì)象适篙。
三、不同寫法有區(qū)別
寫法一
X.prototype.屬性名=值;
X.prototype已經(jīng)先為我們分配一個(gè)對(duì)象了硫痰,并且為我們?cè)谶@個(gè)原型對(duì)象中加入了constructor屬性衩婚。
寫法二
X.prototype ={
屬性名:值
};
這種寫法相當(dāng)于給構(gòu)造函數(shù)的prototype屬性重新指定一個(gè)原型對(duì)象碍论,這個(gè)我們自己定義的原型對(duì)象是沒有constructor屬性的谅猾。
用Object.getOwnPropertyNames()方法打印原型對(duì)象的所有屬性(不包括符號(hào)),看對(duì)比:
如有必要鳍悠,constructor需要自己指定税娜,同時(shí)注意constructor是不可枚舉的屬性。
Object.defineProperty(X.prototype,'constructor',{
enumerable:false,
value:X
});
另外藏研,
實(shí)例對(duì)象的[[prototype]]是在創(chuàng)建實(shí)例時(shí)敬矩,由構(gòu)造函數(shù)的prototype屬性指定的。
如果在創(chuàng)建實(shí)例對(duì)象后蠢挡,給構(gòu)造函數(shù)重新指定原型對(duì)象弧岳,以前創(chuàng)建的實(shí)例對(duì)象的[[prototype]]還是指向舊的原型對(duì)象凳忙。這點(diǎn)要特別注意。
反復(fù)推翻好幾次筆記禽炬,目前認(rèn)為這是最可靠的涧卵。
下次畫Function和Object。