這篇文章的思想主要來源JavaScript 世界萬物誕生記,最後結合一些理解梳理下網上比較經典的一些問題,下次發文章一定會把這些連結帶上
我們在很多地方可能都有聽說過一種說法——JavaScript
萬物皆物件。雖然這種說法不是特別準確,因為我們知道 undefined
就不是個物件,但不可否認的是 JavaScript
中大部分資料都是物件,那麼問題來了,物件產生的先後順序是什麼呢?對於 Object
來說,它是一個 Function
的例項,因為 Object instanceof Function // true
;對於 Function
來說,它是 Object
的例項,因為 Function instanceof Object // true
,所以到底是先有 Object
還是先有 Function
呢?這篇文章主要向大家介紹了 JavaScript
物件的產生過程
混沌初始
我們可以把 JavaScript
世界當作是一家自給自足的工廠,這家工廠可以理解為我們的V8引擎,起初工廠中什麼都沒有,但是工廠認為沒有東西本身就是一種東西呀,所以 null
就出現了
null
造出來一個模版
這個物件可厲害了,是 JavaScript
中物件的始祖,所有的物件追根溯源後都會找到這個物件,這個天字一號元素就是 JavaScript
中的 Object.prototype
,因此在 JavaScript
中 Object.prototype.__proto__ === null
製造物件的機器
好了,既然模版已經存在了,工廠基於這個一個個手動建立不就好了嗎?但是這樣的工廠效率太低下了吧,於是工廠靈機一動,造出了一個機器,用於建立物品(物件)出來,而這些物品的模板就是上述提到的天字一號元素 Object.prototype
Object.prototype
我們通過 new Object
建立一個物件,由於它是以天字一號元素為模板,因此 new Object({}).__proto__ === Object.prototype
製造不同物件的機器
現在工廠可以建立很多個這樣的物品,但是這樣對於工廠來說太單調了,工廠突然有個了想法,我們可以造出更多的機器(也就是 JavaScript
中的 Array
、String
等等)來創造出來不同的物品呀,但是對於機器來說,他本身也是一種物件,現在有了這麼多機器,要把這類的機器物件和我建立出來的具體物品物件給區別開來,於是工廠基於天字一號元素建立天字二號元素
製造機器的機器
好了,現在工廠的世界豐富了起來,不同的機器建立了不同的物品,大家彼此其樂融融,過了一段時間,外部的世界有了一個需求,我不想要這樣的物品,你給我建立一個不同的吧,工廠心想,如果每次都這樣,自己豈不是要累死,於是它建立了一個超級厲害的東西,建立機器的機器,也就是我們所說的 Function
,由於他是建立機器使用的,所以它的模版物件是天字二號元素;但是他本來又是一臺機器,所以天字二號物件的例項
即
Function.__proto__ === Function.prototype
複製程式碼
這也是 JavaScript
中最著名的雞生蛋還是蛋生雞的問題
問題來了
好了現在整個 JavaScript
的世界都正常了,但是這個建立過程還有幾點疑問,留給自己慢慢思考
- 天字一號元素
Object.prototype
是怎麼通過null
建立出來的呢 Function.__proto__ === Function.prototype;
Function
建構函式的prototype
屬性和__proto__
屬性都指向同一個原型,是否可以說Function
物件是由Function
建構函式建立的一個例項
經典圖片
這張圖有助於理解Function
和 Object
的關係,下面通過自己畫一張圖片來解釋一些每條線的解釋
- 紅色的線:
new Object()
的模版物件是Object.prototype
,Object
的原型物件是Object.prototype
,它的模版物件是Function.prototype
,Object.prototype
的模版物件是null
new Object().__proto__ === Object.prototype;
Object.__proto__ === Function.prototype;
Object.prototype.__proto__ === nulll;
複製程式碼
- 黃色的線:
Function
的原型物件和模板物件都是Function.prototype
,Function.prototype
的模板物件是Object.prototype
Function.prototype === Function.__proto__;
Function.prototype.__proto__ === Object.prototype;
複製程式碼
- 黑色的線:
new Foo()
的模版物件是Foo.prototype
,Foo.prototype
的模版物件是Object.prototype
,Foo
的模版物件是Function.prototype
new Foo().__proto__ === Foo.prototype;
Foo.prototype.__proto__ === Object.prototype;
Foo.__proto__ === Function.prototype
複製程式碼
參考文章