JavaScript 入門: 什麼 Prototype(原型) 和 Prototype Chain(原型鏈)

更新 發佈閱讀 10 分鐘

在 JavaScript 中,每個物件都有原型,物件可以從原型繼承屬性和方法,實現程式碼重用。而被繼承的原型物件也可以繼承其他物件,這樣一層又一層被繼承的屬性與方法就形成了原型鏈。


什麼是原型

每個物件都有一個隱藏屬性 [[Prototype]],用來指向該物件的原型物件。原型讓物件可以繼承其他物件的屬性與方法。

原型的用途:

  • 讓物件可以繼承屬性與方法
  • 建立物件之間的關聯
  • 實現程式碼重用
  • 支援 JavaScript 的繼承機制

看起來是不是很像其他語言的 class? 在 JavaScript 中,class 本質上其實只是 prototype 的語法糖。


屬性查找機制

當你存取物件屬性的時候, JavaScript 會先從自身開始找,找不到這個屬性會往 [[Prototype]] 找,再找不到就繼續往上。這條路徑也是我們開頭說的原型鏈。

// 查找屬性步驟
1. 找物件自己
2.[[Prototype]]
3. 往原型物件的 ​[[Prototype]] 繼續找
4. 直到找到屬性或是到 null

Prototype 存取方式

__proto__

obj.__proto__​

getPrototypeOf/setPrototypeOf

Object.getPrototypeOf(obj)  
Object.setPrototypeOf(obj, proto)

Prototype 怎麼繼承

__proto__ 範例

首先建立兩個不相關的物件,一個叫 animal, 一個叫 dog。animal 與 dog 的屬性完全不同。

// 宣告物件 animal 
const animal = {
run: true,
eat(){
console.log("eat!")
}
};
const dog = {
jump: true
};

可以先測試看看 dog.run,因為 dog 沒有 run 這個屬性,因此會印出 undefined

console.log(dog.run); // undefined

接著用 __proto__ 設定 dog 的原型為 animal:

dog.__proto__ = animal;

再操作一次,dog 就可以使用 animal 的屬性與方法了

console.log(dog.run); // true
dog.eat(); // eat!

你也可以再建立更深層的繼承:

// 再建立一個物件,直接將 dog 賦值給 collie 的 __proto__ 屬性​
const collie = {
__proto__: dog
};

原型鏈會像:collie → dog → animal → Object.prototype → null。

大多數物件的原型鏈最終都會到達 Object.prototype,它的 [[Prototype]]null,代表鏈條結束。

建構函式與 new

還記得我們在【JavaScript 入門:物件 (Object )是什麼、要怎麼建立?】就悄悄提過的原型嗎?在介紹建立物件的方法中,我們介紹了「建構函式 + new」的做法,一起來回顧一下當時的程式:

建構函式

// 定義建構函式
function Person(name, age, height, weight){
  // 這邊的 this 指的是即將被 new 出來的物件
  this.name = name;
  this.age = age;
  this.height = height;
  this.weight = weight;
  this.sayHi = function(){
    console.log("Hi");
  }
}
// 使用 new 運算子建立 instance
const person1 = new Person("Elaine", 18, 173, 50);
const person2 = new Person("Tom", 27, 183, 78);

console.log(person1.sayHi === person2.sayHi); // false

這個例子中,我們把 sayHi 方法寫在建構函式中,這代表每 new 一個新物件,物件都有各自的 sayHi,及使用法一模一樣、也出自同一個建構函式。


new 關鍵字

在接著,我們又說了 new 在背後做的事情其實是:

  1. 建立空物件
  2. 將新物件的 [[Prototype]] 隱藏屬性指向建構函式的 prototype 屬性
  3. 將 this 綁定到這個物件
  4. 執行函式的內容
  5. 回傳物件

眼尖的你一定馬上發現了,重點在於第二步的「將新物件的 [[Prototype]] 隱藏屬性指向建構函式的 prototype 屬性」。


prototype 屬性

建構函式的 prototype 屬性是 function 準備給未來 instance 的原型物件,當使用 new 運算子建立 instance 時,new 會讓他們接起來,也就是:

new 會把 instance 的 [[Prototype]] 指向 constructor.prototype

聰明的你一定馬上聯想到了,「物件可以繼承原型的屬性與方法」,所以你會知道,物件共用的方法可以這麼設定:

function Person(name, age, height, weight){
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}
// ​把方法定義在 Person 的 prototype 屬性上,後面 new 出來的物件都可以繼承
Person.prototype.sayHi = function(){
console.log("Hi");
}

const person1 = new Person("Elaine", 18, 173, 50);
const person2 = new Person("Tom", 27, 185, 80);

console.log(person1.sayHi === person2.sayHi); //true

示意圖

// 方法寫在 constructor 內
p1
├─ name
└─ sayHi (一份)
⭡​
p2 不一樣
├─ name ↓
└─ sayHi (另一份)

// 方法寫在 constructor 的 prototype 屬性內
p1 p2
├─ name ├─ name
↓ ↓
[[Prototype]]
└─ sayHi (共用一份)
補充 1:因為 function 本身也是物件,所以他才會有 prototype 屬性唷!
補充 2:prototype 物件本身有一個 constructor 屬性會指回建構函式,這讓整個結構形成閉環
console.log(Person.prototype.constructor === Person); // true

總結

在這篇文章中出現了許多相似的屬性,我在第一次看得時候也覺得有夠複雜有夠難,但是多翻幾篇文章好像有漸漸變得清楚,幫大家快速整理這些相似的屬性:

  • [[Prototype]]:每個物件的隱藏屬性,指向物件的原型物件,是真正決定屬性繼承與原型鏈的機制。
  • prototype:只有建構函式才有的屬性,本身也是一個物件,用來存放將要被 new 出來的實例共享的屬性與方法。
  • __proto__:幾乎所有物件都有的存取器屬性,可用來讀寫物件的原型連接。
  • getPrototypeOf / Object.setPrototypeOf:[[Prototype] 的存取器。

物件繼承並不是複製屬性,而是透過原型鏈查找屬性,因此共享方法可以有效節省記憶體。


參考

  1. 只看一次絕對學不會的 JavaScript 原型指南(一):初探原型、原型繼承與原型鏈
  2. JavaScript Prototype (原型) 是什麼?
  3. 最常見的 JavaScript 原型 (prototype) 面試題 :原型 (prototype)、原型鏈 (prototype chain) 、原型繼承 (prototypal inheritance)
  4. JavaScript 入門:物件 (Object )是什麼、要怎麼建立?
留言
avatar-img
Elaine 粼粼的林林總總
7會員
32內容數
不定期地分享程式/旅遊/學習/閱讀或各式各樣的文章,如果對我的分享有興趣,歡迎來找我玩~
2026/02/23
JavaScript 的 this 總是讓人困惑嗎? 本文詳細解析 5 大綁定規則 (預設、隱式、new、顯式、DOM 事件),包含 call/apply/bind 方法借用、setTimeout 經典陷阱,以及箭頭函式如何完美解決 this 問題。
Thumbnail
2026/02/23
JavaScript 的 this 總是讓人困惑嗎? 本文詳細解析 5 大綁定規則 (預設、隱式、new、顯式、DOM 事件),包含 call/apply/bind 方法借用、setTimeout 經典陷阱,以及箭頭函式如何完美解決 this 問題。
Thumbnail
2026/02/23
本文深入介紹 JavaScript 物件(Object)的核心概念,說明屬性與方法的定義方式、物件字面值與建構函式搭配 new 的差異。同時整理物件的存取方式(dot 與 bracket)、新增、修改、刪除屬性與遍歷技(Object.keys、values、entries)。
2026/02/23
本文深入介紹 JavaScript 物件(Object)的核心概念,說明屬性與方法的定義方式、物件字面值與建構函式搭配 new 的差異。同時整理物件的存取方式(dot 與 bracket)、新增、修改、刪除屬性與遍歷技(Object.keys、values、entries)。
2026/02/21
JavaScript 的動態型別特性容易引發隱性錯誤,本文解析 JavaScript 中常見的型別判斷方法,包括 typeof 、Array.isArray()、instanceof,以及 Object.prototype.toString.call(),並詳述它們的用法、例外情況與常見陷阱。
2026/02/21
JavaScript 的動態型別特性容易引發隱性錯誤,本文解析 JavaScript 中常見的型別判斷方法,包括 typeof 、Array.isArray()、instanceof,以及 Object.prototype.toString.call(),並詳述它們的用法、例外情況與常見陷阱。
看更多
你可能也想看
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
練習目標 這篇是我的前端練習記錄,透過 CodePen 製作一個小功能:「點一下按鈕,就讓整個畫面換個背景色」。 這個練習適合剛開始學習 HTML、CSS、JavaScript 的人,幫助理解: 按鈕怎麼綁定事件 JavaScript 怎麼控制畫面樣式 如何產生隨機顏色 練習畫面預覽
Thumbnail
練習目標 這篇是我的前端練習記錄,透過 CodePen 製作一個小功能:「點一下按鈕,就讓整個畫面換個背景色」。 這個練習適合剛開始學習 HTML、CSS、JavaScript 的人,幫助理解: 按鈕怎麼綁定事件 JavaScript 怎麼控制畫面樣式 如何產生隨機顏色 練習畫面預覽
Thumbnail
這篇文章深入淺出地解釋 JavaScript 中表達式 (expression) 與陳述式 (statement) 的差異,並以 React 中 JSX 的應用為例,說明為何大括號 {} 內只能放入表達式。文章以類比人類語言的句子結構來幫助理解,並提供相關參考資料連結。
Thumbnail
這篇文章深入淺出地解釋 JavaScript 中表達式 (expression) 與陳述式 (statement) 的差異,並以 React 中 JSX 的應用為例,說明為何大括號 {} 內只能放入表達式。文章以類比人類語言的句子結構來幫助理解,並提供相關參考資料連結。
Thumbnail
iFrame在微前端架構中的優缺點,分析了其對用戶體驗、SEO及性能的影響。 iFrame在嵌入小型UI元件、創建隔離環境等特定場景中仍具備相當的應用價值。
Thumbnail
iFrame在微前端架構中的優缺點,分析了其對用戶體驗、SEO及性能的影響。 iFrame在嵌入小型UI元件、創建隔離環境等特定場景中仍具備相當的應用價值。
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
為什麼要登出使用者? 安全性:防止未經授權的人,在使用者暫離時使用系統,這在公用或共享電腦的環境中尤其重要。 資料保護:只要使用者處於登入狀態,就會暴露在個人資料被他人操縱或利用的風險中,因此登出閒置使用者對資安也很重要。 如何在 Vue 3 專案中實作此功能?
Thumbnail
為什麼要登出使用者? 安全性:防止未經授權的人,在使用者暫離時使用系統,這在公用或共享電腦的環境中尤其重要。 資料保護:只要使用者處於登入狀態,就會暴露在個人資料被他人操縱或利用的風險中,因此登出閒置使用者對資安也很重要。 如何在 Vue 3 專案中實作此功能?
Thumbnail
這一集用最新的Vite工具去創建初始檔案。Vite用於創建和構建Web應用程序,具有快速的啟動時間、即時熱更新、小型體積、支持多種框架和可擴展性等優點。
Thumbnail
這一集用最新的Vite工具去創建初始檔案。Vite用於創建和構建Web應用程序,具有快速的啟動時間、即時熱更新、小型體積、支持多種框架和可擴展性等優點。
Thumbnail
隨著科技發展迅速,軟體職缺需求大增長,有些朋友對IT產業有興趣並想成為一位軟體工程師,但不知道從哪裡下手,透過傳統學校、培訓班或自學等不同方法,有多種學習路徑可以選擇。此外,還提供了一些額外資源教學連結,方便讀者進一步提升相關技能。
Thumbnail
隨著科技發展迅速,軟體職缺需求大增長,有些朋友對IT產業有興趣並想成為一位軟體工程師,但不知道從哪裡下手,透過傳統學校、培訓班或自學等不同方法,有多種學習路徑可以選擇。此外,還提供了一些額外資源教學連結,方便讀者進一步提升相關技能。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News