Prototype,__proto__,Function,Object

最近地鐵上重讀了《Javascript語言精粹和編程實踐》,又有了新的理解。

原型繼承

面向?qū)ο蟮恼Z言有三個特性,即封裝性、繼承和多態(tài)。一般來說,三個特性都滿足,即稱為“面向?qū)ο笳Z言”。

“對象系統(tǒng)”的繼承特性有三種實現(xiàn)方案,基于類(class-based)、基于原型(prototype-based)和基于元類(metaclass-based)。Javascript采用了基于原型繼承實現(xiàn)對象系統(tǒng)。采用“構(gòu)造器(constructor)”的機(jī)制實現(xiàn)類的功用。

在JavaScript中,函數(shù)創(chuàng)建之后都會有一個prototype屬性,這個屬性指向函數(shù)的原型對象,同時原型對象的 constructor屬性又指向構(gòu)造函數(shù)本身。

即:

function T(){
  //構(gòu)造函數(shù)
}
T.prototype === 原型對象
T = T.prototype.constructor

在JavaScript語言和對象系統(tǒng)的實現(xiàn)中,對象(Object)并沒有原型,而構(gòu)造器有原型,屬性"<構(gòu)造器>.prototype"指向原型。對象只有“構(gòu)造自某個原型”,不存在“擁有某個原型”。

原型也是對象,即原型是對象的一個實例。原型的含義是指:如果構(gòu)造器有一個原型對象A,那么由該構(gòu)造器創(chuàng)建的實例(instance)都復(fù)制自A。所以實例繼承了A的所有屬性、方法和其他性質(zhì)。

原型也是對象實例

假設(shè)有一個構(gòu)造器T , T的原型對象為M,T是一個函數(shù)(Function),M是一個對象(OBJECT)。

即:T.prototype = M

原型對象M中含有一個constructor 屬性指向構(gòu)造器本身。

即 M.constructor = T = T.prototype.constructor

而同時原型對象 M 也是 對象(OBJECT)的一個實例。而對象(OBJECT)同時也是構(gòu)造器。那么Object 的原型對象是什么呢?實現(xiàn)一下我們可以得到:

Object.prototype  //  {} 空的對象

因為Object也是構(gòu)造器,即Object也是函數(shù),所以

Object.constructor  // Function

而對Function來說,F(xiàn)unction也是一個函數(shù),同時也是一個構(gòu)造器,function的原型對象是

Function.prototype

我從MDN上找到一段描述:

The **Function.prototype** property represents the Function prototype object.

Function objects inherit from Function.prototype. Function.prototype cannot be modified.

Function.prototype屬性存儲了Function的原型對象。Function對象繼承自Function.prototype屬性,因此,F(xiàn)unction.prototype不能被修改。

那么 ,F(xiàn)unction的原型對象Function.prototype 同時也是Object的一個實例。

原型鏈

在JavaScript,每個函數(shù)都有一個prototype屬性,指向構(gòu)造器的原型,而在對象上,都有一個隱式的__proto__屬性,指向原型。

即:__proto__ === constructor.prototype

那么構(gòu)造器 對象的(Object)的原型對象 Object.prototype 為 空的對象。

所以O(shè)ject.prototype是所有對象的根源 {}

而Function.prototype則構(gòu)造自 Object.prototype上。

Function.prototype.__proto__ = Object.prototype

而空的對象 {} (Object.prototype) 來自 null

即 Object.prototype.__proto__ === null //true

屬性查找

當(dāng)查找一個對象的屬性時,Javascript會向上遍歷原型鏈,直到找到給定名稱的屬性為止,如果查找到原型鏈頂端——Object.prototype——仍然沒有找到指定屬性,那么就會返回undefined。

對象的屬性在查找時,先查找自身的屬性,然后查找原型,再往上到Object的原型上。

hasOwnProperty函數(shù):

hasOwnProperty是Object.prototype的一個方法,它可是個好東西,他能判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性,因為hasOwnProperty 是 JavaScript 中唯一一個處理屬性但是不查找原型鏈的函數(shù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容