ECMAScript規定了兩個特殊的內置對象:Object和Function。他們的特殊性在於,他們自己既是對象又是函數,而他們同時也是對象和函數的構造器。這種本身生本身的邏輯顯然違反人性,若是還停留在類的繼承的思想上,那麼更加沒法理解。html
然而ECMAScript是基於原型鏈的,因此忘掉類的繼承,從原型鏈入手:原型鏈是對象的集合,每一個對象都有內部屬性[[Prototype]](注1)指向另外一個對象;當訪問對象某一屬性的時候,若是此屬性不爲此對象的自身屬性(注2),則繼續去[[Prototype]]指向的對象上查找此屬性。[[Prototype]]造成的對象的鏈式集合即原型鏈。這裏能夠得出:原型鏈上的全部元素都是對象。瀏覽器
ECMASciprt規定:原型鏈必須是有限長度(注3),並且終點必須是null。如今終點是惟一的,那麼原型鏈上倒數第二個元素是否是惟一的呢?ECMAScript沒有規定,但從實現上來看,是惟一的。由於原型鏈上全部的元素都是對象,因此倒數第二個元素應該是全部對象的基礎對象。這個對象在實現中只給出一個引用,就是Object.prototype。這裏能夠得出:原型鏈上有兩個元素是固定的,終點是null,倒數第二的元素是Object.prototype指向的對象(注4)。函數
那麼倒數第三個元素是否是固定的呢?不是。從倒數第二個元素是Object.prototype來看,經過{}字面量和new Object()建立的對象都在倒數第三這個位置,即POJO都在倒數第三。另外還有兩個特例,一個是除內置函數以外的內置對象,如Math、JSON;一個是除Object以外的內置函數的prototype屬性指向的對象,如Function.prototype。這裏能夠得出:原型鏈上倒數第三的元素通常是POJO+Math/JSON+(Function/Array/String/Boolean/Number/Date/RegExp/Error).prototype。spa
倒數第三的位置出現了這麼多的prototype,那麼倒數第四的位置就好推測了,全部除Object以外的內置函數做爲構造器調用(注5)時生成的實例對象都在倒數第四。其中須要注意的是,全部的內置函數自己是Function做爲構造器調用生成的實例對象,因此都在這個位置。這裏能夠得出:原型鏈上倒數第四的元素通常是(Function/Array/String/Boolean/Number/Date/RegExp/Error)實例,其中包括(Object/Function/Array/String/Boolean/Number/Date/RegExp/Error),注意這個括號裏面Object回來了。prototype
原型鏈基本結構以下圖:code
從圖上看來:htm
參考文檔:ES5對象
注:blog
var a = {}; a.__proto__ = a;