前端三十|15. [JS] 什麼是原型鏈?

Schaos
Schaos’s Blog
Published in
10 min readOct 1, 2019

--

今天是鐵人賽的第十五天,旅程進行到了一半,而本系列文 JavaScript 的部分也即將告一段落。經過了連續三天型別相關的內容,今天也將接續下去,跟大家聊聊許多開發者時常搞不清楚的「物件原型」及「原型鏈」。

本系列文已經重新編校彙整編輯成冊,並正式出版囉!

前端三十:從 HTML 到瀏覽器渲染的前端開發者必備心法好評販售中!

喜歡我文章內容的讀者們,歡迎您前往購買支持

物件原型

相信大家多少都有用過 map 將陣列內容依序處理的經驗吧?例如:

let arr = [0, 1, 2]
let doubleArr = arr.map(c => c * 2)
console.log(doubleArr) // 0, 2, 4

不知道你有沒有曾好奇過,像這邊的變數 arr,本身並沒有設定 map 屬性,那為什麼可以使用 map 這個函式呢?

我們將它印出來看看:

console.log(arr)
// 0: 0
// 1: 1
// 2: 2
// length: 3
// __proto__: Array(0)

出現了名為 __proto__ 的物件,我們可以再將其展開,便會看到所有 Array 物件可以使用的函式;當然,我們也可以在其中找到 map 函式,而這也正是我們範例中呼叫 arr.map 的那個函式:

console.log(arr.map === arr.__proto__.map) // true

這邊出現的 __proto__ 物件,也就是所謂的 原型物件(Prototype)

不同於 Java、C# 等 基於類別(Class) 的物件導向程式語言,藉由透過定義 Class、建立實例(instance)、指定繼承等方式來傳遞屬性及方法;Javascript 則是個 基於原型(Prototype)的物件導向程式語言 ,透過預先建立出的原型物件,每當新物件建立時,便指定物件的原型要參照到哪個原型物件。

而當開發者呼叫物件的屬性或方法時,若物件本身沒有這項屬性/方法,JavaScript 會自動尋找它原型中的方法,這也就是為什麼我們可以直接呼叫 arr.map 而不會出錯的原因了。

原型鏈

眼尖的讀者可能已經發現了,在前述的例子中,__proto__ 物件中仍然有 __proto__ 屬性:

console.log(arr.__proto__) // Array 的

--

--