Logo

JavaScript Class 簡介

Dec 20, 2025
23 min read

簡介

JavaScript 在 ECMAScript 2015(ES6)正式引入 class 語法,作為既有 prototype 繼承模型的語法糖(syntax sugar)。本質上,JavaScript 仍然是以 prototype 為核心的語言,但 class 大幅改善了可讀性與可維護性,讓開發者能以更接近傳統物件導向(OOP)的方式來組織程式碼。因此,理解 JavaScript class 的設計定位與實際使用情境,會對大型前端或全端專案非常有幫助。


如何定義 Class

JavaScript 使用 class 關鍵字來宣告類別,並透過 constructor 定義初始化行為:

js
1class Person { 2 constructor(name, age) { 3 this.name = name; 4 this.age = age; 5 } 6 7 greet() { 8 console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); 9 } 10} 11 12const john = new Person("John", 30); 13john.greet();

注意事項

  • constructornew 時會自動呼叫
  • class method 預設定義在 prototype 上(不會每次 new 都產生一份)
  • class 本身不會被 hoist(與 function declaration 不同)

Class vs Prototype

在瞭解 class 和 prototype 之前,有一點重要的前提:class 並沒有取代 prototype,只是包裝它。

Prototype 寫法(ES5)

js
1function Person(name, age) { 2 this.name = name; 3 this.age = age; 4} 5 6Person.prototype.greet = function () { 7 console.log(`Hello, my name is ${this.name}`); 8};

Class 寫法(ES6+)

js
1class Person { 2 constructor(name, age) { 3 this.name = name; 4 this.age = age; 5 } 6 7 greet() { 8 console.log(`Hello, my name is ${this.name}`); 9 } 10}

Class vs Prototype

PrototypeClass
可讀性偏低
繼承語法手動處理extends / super
理解成本
本質prototype chainprototype chain(包裝)

注意事項

在實際專案中,大多數情況直接用 class 就可以;只有在寫底層 library,或真的需要精細控制 prototype 時,才需要使用 prototype。


Class 繼承(Inheritance)

使用 extends 來建立繼承關係,並透過 super() 呼叫父類別的 constructor:

js
1class Employee extends Person { 2 constructor(name, age, jobTitle) { 3 super(name, age); 4 this.jobTitle = jobTitle; 5 } 6 7 work() { 8 console.log(`${this.name} is working as a ${this.jobTitle}.`); 9 } 10}

注意事項

  • super() 必須在子類別 constructor 中最先呼叫
  • 方法覆寫(override)時,可搭配 super.method() 使用

Static 方法與 Getters / Setters

JavaScript class 提供了 static 方法與 getter / setter ,但若設計不當,也容易讓 class 變得難以理解。

Static 方法

static 方法屬於 class 本身,而不是某一個 instance,適合用於:

  • 工具型邏輯(utility)
  • factory function
  • 與 domain 無關的純計算
js
1class MathUtil { 2 static add(a, b) { 3 return a + b; 4 } 5} 6 7MathUtil.add(2, 3); // 5

注意事項

  • 如果方法不需要 this 狀態,優先考慮使用 static
  • static 方法通常是「輸入 → 輸出」,不產生副作用(side effect)

Getters / Setters

getter / setter 讓我們可以在不改變使用方式的情況下,控制資料的存取行為。

js
1class Car { 2 constructor(brand) { 3 this._brand = brand; 4 } 5 6 get brand() { 7 return this._brand; 8 } 9 10 set brand(value) { 11 if (!value) { 12 throw new Error("Brand is required"); 13 } 14 this._brand = value; 15 } 16} 17 18const car = new Car("Toyota"); 19console.log(car.brand); // Toyota 20car.brand = "Honda";

為什麼不用 public property?

  • 可在 setter 中加入驗證邏輯
  • 可加入 side effect(log / sync)而不影響外部 API

注意事項

  • 避免在 getter 中使用昂貴的運算或是打 API
  • getter 適合「處理速度快、同步、無副作用」的邏輯
  • setter 不應承擔複雜 business logic

常見的 OOP 設計模式

單例模式(Singleton)

確保整個應用中只存在一個實例,常見於 logger、config manager。

js
1class ConfigService { 2 static instance; 3 4 constructor() { 5 if (ConfigService.instance) { 6 return ConfigService.instance; 7 } 8 this.config = {}; 9 ConfigService.instance = this; 10 } 11} 12 13const service1 = new ConfigService(); 14const service2 = new ConfigService(); 15console.log(service1 === service2); // true

工廠模式(Factory)

根據不同條件,產生不同類型的物件。

js
1class Dog { 2 speak() { 3 return "Woof"; 4 } 5} 6 7class Cat { 8 speak() { 9 return "Meow"; 10 } 11} 12 13class AnimalFactory { 14 static create(type) { 15 switch (type) { 16 case "dog": 17 return new Dog(); 18 case "cat": 19 return new Cat(); 20 default: 21 throw new Error("Unknown animal type"); 22 } 23 } 24}

繼承 + 組合:避免過深繼承

在大型系統中,組合(composition)通常比繼承更安全。

js
1class Logger { 2 log(message) { 3 console.log(message); 4 } 5} 6 7class UserService { 8 constructor(logger) { 9 this.logger = logger; 10 } 11}

Error Handling Patterns

Class 的 constructor 很容易成為 bug 溫床,尤其在參數不可信時,所以盡量要加上 error handling。

js
1class User { 2 constructor(email) { 3 if (!email) { 4 throw new Error("Email is required"); 5 } 6 this.email = email; 7 } 8}

設計準則

  • 在 constructor 做最基本的 guard
  • 複雜驗證邏輯抽成 factory function
  • 盡量避免 constructor 裡面有 async 的行為

結論

JavaScript class 並不是新的語言核心,而是讓 prototype 更容易被正確使用的工具。在中大型專案中,搭配良好的分層設計、適度的設計模式,class 可以有效提升可讀性、可維護性與團隊協作效率。