iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 28
0
Modern Web

前端開發 30 個問題系列 第 28

Prototype chain

前言
2020 秋天,我將用 30 天的時間,來嘗試回答和網路前端開發相關的 30 個問題。30 天無法一網打盡浩瀚的前端知識,有些問題可能對有些讀者來說相對簡單,不過期待這趟旅程,能幫助自己、也幫助讀者打開不同的知識大門。有興趣的話,跟著我一起探索吧!

今天想來談談 JavaScript 當中的 prototype chain,不過,我想偷懶一下,不打算從頭談起。如果是第一次接觸到 prototype chain 的朋友,可以先閱讀以下兩篇文章:

那我今天要幹嘛呢?其實我一直想做一件事情,就是透過圖解來表達 prototype chain 錯綜復雜的關係。於是,我就畫出了下面這張圖了:

圖中有四個物件,分別為

左上角:JavaScript Function
右上角:JavaScript Object
左下角:使用者自己建立的 Person class

function Person (name, age){
    this.name = name
    this.age = age
}
Person.prototype.greet = function (){
    console.log('Hello!')
}

右下角:使用者建立的 Person instance, tim

const tim = new Person('tim', 18)

人物介紹完畢之後,接下來,就可以來解釋那張圖當中物件與線條的關係了!


關於 Person class,最初的 function 當中只有設定 nameage 兩個 properties,而 greet method 是後來直接加入到 Person 的 prototype 裡面。

藍色線段

因為 tim 是 Person 的 instance,因此可以透過 __proto__ 來找到(指向) Person 放在 prototype 裡面的東西,也就是說

tim.__proto__ === Person.prototype    // true

紅色線段

當我們想要呼叫 tim.greet() ,這時候發現 tim 本身並沒有 greet 這個方法,因為當初 greet 不在 Person 的 contructor 當中,是後來才加入到 Person 的 prototype 當中。

所以,當無法在 tim 當中找到 greet 方法的時候,就會透過 prototype chain (__proto__) 往回找,看看 Person 的 prototype 中有沒有這個方法。若有,就可以直接執行;若無,就會一路透過 __proto__ 往回找,一最終找到 JavaScript 的 Object 之上。

另一方面,這時候的 tim 並沒有prototype 這個屬性。所以

tim.prototype                         // undefined

棕色線段
因為 Person class 本身是由 JavaScript Function 實作而來,因此在 prototype chain 當中,Person 的 __proto__ 會指向 Function 的 prototype

Person.__proto__ === Function.prototype  // true

深綠色線段
那如果是 Person 的 prototype 當中的 __proto__ 呢?則會指向 JavaScript Object 的 prototype

Person.prototype.__proto__ === Object.prototype  // true

Person class 當中的 prototype 本身是個物件,所以也就繼承自 JavaScript Object


紫色線段
接下來就會進入 JavaScript 當中 Function 和 Object 的複雜關係

首先,Function 的 __proto__ 會指向自己的 prototype

Function.__proto__ === Function.prototype  // true

粉紅色線段
接著,Function 的 prototype 當中的 __proto__ 會指向 Object 的 prototype

Function.proto.__proto__ === Object.prototype  // true

橘色線段

然後很妙的是,JavaScript Object 的 __proto__ 指回了 Function 的 prototype

Object.__proto__ === Function.prototype  // true

黑色虛線段

最後,Object 當中的 prototype__proto__ 指向 null(結束這段複雜的關係)

Object.prototype.__proto__ === null  // true

End

雖然還不知道 Function 和 Object 之間錯綜復雜的關係為什麼要這樣設計,不過希望透過圖解,能夠幫助大家更理解 prototype chain 的關係。我們明天見啦!

Ref


TD
Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player

More about me

"Life is like riding a bicycle. To keep your balance, you must keep moving."


上一篇
NaN, not a number
下一篇
Event loop, macrotask and microtask
系列文
前端開發 30 個問題31

尚未有邦友留言

立即登入留言