JavaScript萬物產生順序

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

咱們在不少地方可能都有據說過一種說法——JavaScript 萬物皆對象。雖然這種說法不是特別準確,由於咱們知道 undefined 就不是個對象,但不能否認的是 JavaScript 中大部分數據都是對象,那麼問題來了,對象產生的前後順序是什麼呢?對於 Object 來講,它是一個 Function的實例,由於 Object instanceof Function // true;對於 Function 來講,它是 Object 的實例,由於 Function instanceof Object // true,因此究竟是先有 Object 仍是先有 Function呢?這篇文章主要向你們介紹了 JavaScript 對象的產生過程函數

混沌初始

咱們能夠把 JavaScript 世界看成是一家自給自足的工廠,這家工廠能夠理解爲咱們的V8引擎,起初工廠中什麼都沒有,可是工廠認爲沒有東西自己就是一種東西呀,因此 null 就出現了spa

萬物之始
工廠想創造一些物品(也就是對象)出來,可是如今沒有建立物品的(模版原料),因此工廠就基於 null 造出來一個模版
這個對象可厲害了,是 JavaScript 中對象的始祖,全部的對象追根溯源後都會找到這個對象,這個天字一號元素就是 JavaScript 中的 Object.prototype,所以在 JavaScriptObject.prototype.__proto__ === null

製造對象的機器

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

如今咱們就能夠基於這臺機器來源源不斷的建立物品了,它的模版是 Object.prototype

咱們經過 new Object 建立一個對象,因爲它是以天字一號元素爲模板,所以 new Object({}).__proto__ === Object.prototype

製造不一樣對象的機器

如今工廠能夠建立不少個這樣的物品,可是這樣對於工廠來講太單調了,工廠忽然有個了想法,咱們能夠造出更多的機器(也就是 JavaScript 中的 ArrayString等等)來創造出來不一樣的物品呀,可是對於機器來講,他自己也是一種對象,如今有了這麼多機器,要把這類的機器對象和我建立出來的具體物品對象給區別開來,因而工廠基於天字一號元素建立天字二號元素3d

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

製造機器的機器

好了,如今工廠的世界豐富了起來,不一樣的機器建立了不一樣的物品,你們彼此其樂融融,過了一段時間,外部的世界有了一個需求,我不想要這樣的物品,你給我建立一個不一樣的吧,工廠心想,若是每次都這樣,本身豈不是要累死,因而它建立了一個超級厲害的東西,建立機器的機器,也就是咱們所說的 Function,因爲他是建立機器使用的,因此它的模版對象是天字二號元素;可是他原本又是一臺機器,因此天字二號對象的實例 即code

Function.__proto__ === Function.prototype
複製代碼

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

問題來了

好了如今整個 JavaScript 的世界都正常了,可是這個建立過程還有幾點疑問,留給本身慢慢思考對象

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

經典圖片

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

  • 紅色的線: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
複製代碼

參考文章blog

相關文章
相關標籤/搜索