說到原型就不得不說構(gòu)造函數(shù),js一切皆對(duì)象,但分為普通對(duì)象和函數(shù)對(duì)象,構(gòu)造函數(shù)就屬于函數(shù)對(duì)象,所謂的原型和繼承也是在函數(shù)對(duì)象下實(shí)現(xiàn)的
了解原型與原型鏈需要知道的三個(gè)構(gòu)造函數(shù)屬性(prototype, __proto__, constructor)
1.?prototype、__proto__
prototype:原型是函數(shù)類型對(duì)象的一個(gè)自帶屬性'prototype',這個(gè)屬性其實(shí)也是一個(gè)對(duì)象,有自己的屬性和方法,通過原型可以實(shí)現(xiàn)對(duì)象的屬性繼承,null和undefined沒有原型和原型鏈。
__proto__: “prototype”作為對(duì)象的內(nèi)部屬性,是不能被直接訪問的,F(xiàn)irefox和Chrome中提供了__proto__這個(gè)非標(biāo)準(zhǔn)(不是所有瀏覽器都支持)? ? ? ?的訪問器(ECMA引入了標(biāo)準(zhǔn)對(duì)象原型訪問器”O(jiān)bject.getPrototype(object)”)。

那么一個(gè)對(duì)象的[[prototype]]屬性究竟怎么決定呢?這是由構(gòu)造該對(duì)象的方法決定的。據(jù)我所知有三種構(gòu)造一個(gè)對(duì)象的方法:

然而雖然說[[prototype]]是一個(gè)隱藏屬性,但很多瀏覽器都給每一個(gè)對(duì)象提供.__proto__這一屬性,這個(gè)屬性就是上文反復(fù)提到的該對(duì)象的[[prototype]]。由于這個(gè)屬性不標(biāo)準(zhǔn),因此一般不提倡使用。ES5中用Object.getPrototypeOf函數(shù)獲得一個(gè)對(duì)象的[[prototype]]。ES6中,使用Object.setPrototypeOf可以直接修改一個(gè)對(duì)象的[[prototype]]
2. 在JavaScript的原型對(duì)象中,還包含一個(gè)”constructor”屬性,這個(gè)屬性對(duì)應(yīng)當(dāng)前對(duì)象原型的實(shí)例的構(gòu)造函數(shù)。
object.constructor指向object的構(gòu)造函數(shù),而構(gòu)造函數(shù)的constructor指向的也是自己本身,所以object.constructor.constructor........。最后還是指向的是object的構(gòu)造函數(shù)本身,
constructor屬性不影響任何JavaScript的內(nèi)部屬性。instanceof檢測(cè)對(duì)象的原型鏈,通常你是無法修改的(不過某些引擎通過私有的__proto__屬性暴露出來)。constructor其實(shí)沒有什么用處,只是JavaScript語言設(shè)計(jì)的歷史遺留物。由于constructor屬性是可以變更的,所以未必真的指向?qū)ο蟮臉?gòu)造函數(shù),只是一個(gè)提示。不過,從編程習(xí)慣上,我們應(yīng)該盡量讓對(duì)象的constructor指向其構(gòu)造函數(shù),以維持這個(gè)慣例。