前言
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 當中只有設定 name 和 age 兩個 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
雖然還不知道 Function 和 Object 之間錯綜復雜的關係為什麼要這樣設計,不過希望透過圖解,能夠幫助大家更理解 prototype chain 的關係。我們明天見啦!
TD
Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player"Life is like riding a bicycle. To keep your balance, you must keep moving."