JavaScript萬物產生順序

NO IMAGE

這篇文章的思想主要來源JavaScript 世界萬物誕生記,最後結合一些理解梳理下網上比較經典的一些問題,下次發文章一定會把這些鏈接帶上

我們在很多地方可能都有聽說過一種說法——JavaScript 萬物皆對象。雖然這種說法不是特別準確,因為我們知道 undefined 就不是個對象,但不可否認的是 JavaScript 中大部分數據都是對象,那麼問題來了,對象產生的先後順序是什麼呢?對於 Object 來說,它是一個 Function的實例,因為 Object instanceof Function // true;對於 Function 來說,它是 Object 的實例,因為 Function instanceof Object // true,所以到底是先有 Object 還是先有 Function呢?這篇文章主要向大家介紹了 JavaScript 對象的產生過程

混沌初始

我們可以把 JavaScript 世界當作是一家自給自足的工廠,這家工廠可以理解為我們的V8引擎,起初工廠中什麼都沒有,但是工廠認為沒有東西本身就是一種東西呀,所以 null 就出現了

JavaScript萬物產生順序

工廠想創造一些物品(也就是對象)出來,但是現在沒有創建物品的(模版原料),所以工廠就基於 null 造出來一個模版

JavaScript萬物產生順序

這個對象可厲害了,是 JavaScript 中對象的始祖,所有的對象追根溯源後都會找到這個對象,這個天字一號元素就是 JavaScript 中的 Object.prototype,因此在 JavaScriptObject.prototype.__proto__ === null

製造對象的機器

好了,既然模版已經存在了,工廠基於這個一個個手動創建不就好了嗎?但是這樣的工廠效率太低下了吧,於是工廠靈機一動,造出了一個機器,用於創建物品(對象)出來,而這些物品的模板就是上述提到的天字一號元素 Object.prototype

JavaScript萬物產生順序

現在我們就可以基於這臺機器來源源不斷的創建物品了,它的模版是 Object.prototype

JavaScript萬物產生順序

我們通過 new Object 創建一個對象,由於它是以天字一號元素為模板,因此 new Object({}).__proto__ === Object.prototype

製造不同對象的機器

現在工廠可以創建很多個這樣的物品,但是這樣對於工廠來說太單調了,工廠突然有個了想法,我們可以造出更多的機器(也就是 JavaScript 中的 ArrayString等等)來創造出來不同的物品呀,但是對於機器來說,他本身也是一種對象,現在有了這麼多機器,要把這類的機器對象和我創建出來的具體物品對象給區別開來,於是工廠基於天字一號元素創建天字二號元素

JavaScript萬物產生順序

這個天字二號元素是機器的模版對象,也就是說,每個機器都是它的實例

JavaScript萬物產生順序

製造機器的機器

好了,現在工廠的世界豐富了起來,不同的機器創建了不同的物品,大家彼此其樂融融,過了一段時間,外部的世界有了一個需求,我不想要這樣的物品,你給我創建一個不同的吧,工廠心想,如果每次都這樣,自己豈不是要累死,於是它創建了一個超級厲害的東西,創建機器的機器,也就是我們所說的 Function,由於他是創建機器使用的,所以它的模版對象是天字二號元素;但是他本來又是一臺機器,所以天字二號對象的實例

Function.__proto__ === Function.prototype

這也是 JavaScript 中最著名的雞生蛋還是蛋生雞的問題

JavaScript萬物產生順序

問題來了

好了現在整個 JavaScript 的世界都正常了,但是這個創建過程還有幾點疑問,留給自己慢慢思考

  • 天字一號元素 Object.prototype 是怎麼通過 null 創建出來的呢
  • Function.__proto__ === Function.prototype;
    Function 構造函數的 prototype 屬性和 __proto__ 屬性都指向同一個原型,是否可以說 Function 對象是由 Function 構造函數創建的一個實例

經典圖片

JavaScript萬物產生順序

這張圖有助於理解 FunctionObject 的關係,下面通過自己畫一張圖片來解釋一些每條線的解釋

JavaScript萬物產生順序

  • 紅色的線:new Object() 的模版對象是 Object.prototypeObject 的原型對象是 Object.prototype,它的模版對象是 Function.prototypeObject.prototype 的模版對象是 null
new Object().__proto__ === Object.prototype;
Object.__proto__ === Function.prototype;
Object.prototype.__proto__ === nulll;
  • 黃色的線:Function 的原型對象和模板對象都是 Function.prototypeFunction.prototype的模板對象是 Object.prototype
Function.prototype === Function.__proto__;
Function.prototype.__proto__ === Object.prototype;
  • 黑色的線:new Foo() 的模版對象是 Foo.prototypeFoo.prototype的模版對象是 Object.prototypeFoo的模版對象是 Function.prototype
new Foo().__proto__ === Foo.prototype;
Foo.prototype.__proto__ === Object.prototype;
Foo.__proto__ === Function.prototype

參考文章

相關文章

你知道支付寶容器化架構是怎麼搭建的嗎?

關於三次握手與四次揮手的那些事,你真的明白了嗎?不看後悔系列

webpack編譯優化

CSS垂直居中的12種實現方式