JavaScript原型鏈中函數和對象的理解
__ proto__
最近在看高程4,原型鏈肯定是繞不過的,本瓜之前一直認為,只要記住這句話就可以了:
一個對象的隱式原型(__proto__)等于構造這個對象的構造函數的顯式原型(prototype)
確實,所有對象都符合這句真理,在控制臺打印一試便知:
const str = new String("123") str.__proto__ === String.prototype // true const arr = new Array(["123"]) arr.__proto__ === Array.prototype // true const obj = new Object() obj.__proto__ === Object.prototype // true const bl = new Boolean(false) bl.__proto__ === Boolean.prototype // true ...... const fn = function(){} fn.__proto__ === Function.prototype // true
雖然我們平常都會像以下這樣寫居多,聲明方式不一樣,但結果不變:
const str = '123' str.__proto__ === String.prototype // true const arr = [123] arr.__proto__ === Array.prototype // true const obj = {} obj.__proto__ === Object.prototype // true const bl = false bl.__proto__ === Boolean.prototype // true ...... const fn = new Function() fn.__proto__ === Function.prototype // true
順著這個思路,那我們接著在構造函數上,繼續(xù)用 __proto__ 尋找,可以得到:
String.__proto__=== Function.prototype // true Array.__proto__=== Function.prototype // true Boolean.__proto__=== Function.prototype // true Object.__proto__=== Function.prototype // true Function.__proto__=== Function.prototype // true
這些基本構造函數(String、Array、Boolean、Object 等),都是用 Function 來構造生成的!!
還能用 __proto__ 繼續(xù)向上找嗎? 不能了,因為結果會是一直重復下面這一行代碼:
Function.__proto__ === Function.prototype
所以,不管你怎樣通 __proto__ 隱式原型向上找,最終都只能找到 Function,而 Function 的隱式原型等于它的顯式原型;
prototype.__ proto__
但是這與我們所知不符呀,不是萬物皆對象嗎??
我們嘗試再用 __proto__ 向前探一步,發(fā)現:
Function.__proto__.__proto__ === Object.prototype // true Function.__proto__ === Function.prototype // true Function.prototype.__proto__ === Object.prototype // true
Function 這個終極構造函數,通過查找顯式原型的隱式原型,竟然等于 Object 的顯式原型!
其實,其它構造函數也一樣,都能找到 Object:
String.prototype.__proto__=== Object.prototype // true Array.prototype.__proto__=== Object.prototype // true Boolean.prototype.__proto__=== Object.prototype // true Object.prototype.__proto__=== Object.prototype // true
所有構造函數的顯式原型的隱式原型 等于 Object 的顯式原型??!
理解
為什么要這樣設定呢??
為什么對象只用 .__proto__ 向上查找,最終只能找到 Function?
為什么構造函數用 .prototype.__proto__ 向上查找,能找到 Object ?
這樣原型鏈查找不是有兩套邏輯嗎?
后來,本瓜歪理解:
【Function】就好像是創(chuàng)造萬物的上帝,它創(chuàng)造了:各種各樣的物質【對象】,物質又分化為:人【字符串】、魚【數組】、鳥【布爾】、獸【數值】、石頭【Date】、花草【正則】等等分類;
這些不同種類的物質,再一代一代延續(xù)(繁衍)下去。。。。。。
問:這些種類,它們子孫或后代們的特性【屬性】是來源于哪里呢??
1.可以從它們的祖先那里繼承而來,這一點沒毛病,生物 DNA 遺傳,龍生龍、鳳生鳳,老鼠兒子會打洞
let Mouse = function(){ this.makeAHole = true } let m1 = new Mouse() m1.makeAHole // true m1.__proto__.makeAHole === Mouse.prototype.makeAHole // true
2.或者還可以從【物質】這個原始分類而來, 因為人魚鳥獸、花草樹木、石頭都還是屬于“物質”,比如都有碳元素,就像字符串、數組、布爾、數值都是屬于“對象”,都有 toString 方法;
Object.prototype.carbon = true let p1 = 'man' p1.carbon // true p1.__proto__.__proto__.carbon === Object.prototype.carbon// true
對象 Object(物質)是由函數 Function(上帝)創(chuàng)造的,沒毛病。
上帝(Function)也是一種物質(Object),一切都是物質(Object),物質(Object)起源于大爆炸,起源于空(null),也沒毛病。
再來看這張經典的圖:
按照咱們“理解”也畫一個:
哈哈哈,害行,這次就先理解到這吧,更多關于JavaScript原型鏈函數對象的資料請關注腳本之家其它相關文章!