首頁 > 軟體

JavaScript原型鏈中函數和物件的理解

2022-06-15 14:02:31

__ 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

順著這個思路,那我們接著在建構函式上,繼續用 __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__ 繼續向上找嗎? 不能了,因為結果會是一直重複下面這一行程式碼:

Function.__proto__ === Function.prototype

所以,不管你怎樣通 __proto__ 隱式原型向上找,最終都只能找到 Function,而 Function 的隱式原型等於它的顯式原型;

prototype.__ proto__

但是這與我們所知不符呀,不是萬物皆物件嗎??

我們嘗試再用 __proto__ 向前探一步,發現:

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】就好像是創造萬物的上帝,它創造了:各種各樣的物質【物件】,物質又分化為:人【字串】、魚【陣列】、鳥【布林】、獸【數值】、石頭【Date】、花草【正則】等等分類;

這些不同種類的物質,再一代一代延續(繁衍)下去。。。。。。

問:這些種類,它們子孫或後代們的特性【屬性】是來源於哪裡呢??

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(上帝)創造的,沒毛病。

上帝(Function)也是一種物質(Object),一切都是物質(Object),物質(Object)起源於大爆炸,起源於空(null),也沒毛病。

再來看這張經典的圖:

按照咱們“理解”也畫一個:

哈哈哈,害行,這次就先理解到這吧,更多關於JavaScript原型鏈函數物件的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com