Class 是 OOP 必備觀念,ECMAScript 2015 總算支援 Class,讓很多人倍感親切,但事實上 ECMAScript 的 Class 並非如你想得這麼單純。
Version
macOS Catalina 10.15.2
VS Code 1.41.1
Quokka 1.0.267
ECMAScript 2015
Class
class Book {
constructor(title, price) {
this.title = title
this.price = price
}
showDescription() {
return `${this.title} / ${this.price}`
}
}
let book = new Book('FP in JavaScript', 100)
book.showDescription() // ?
這是典型 ES6 的 class 寫法,由 constructor keyword 定義 constructor,且 method 直接定義在 class 內,而非透過 prototype 新增 method,十足 OOP 風,一切看似完美。

typeof Operator
class Book {
constructor(title, price) {
this.title = title
this.price = price
}
showDescription() {
return `${this.title} / ${this.price}`
}
}
typeof Book // ?
若使用 typeof 判斷 Book 型別,竟然回傳 function。

這已經告知 class 實際上只是 constructor function 的 syntatic sugar,Book class 在底層仍是 Book() function,只是看起來像 class 而已。
Book.prototype.constructor
class Book {
constructor(title, price) {
this.title = title
this.price = price
}
showDescription() {
return `${this.title} / ${this.price}`
}
}
Book === Book.prototype.constructor // ?
若判斷 Book class 與 Book.prototype.constructor 會回傳 true,也就是根本指向相同 object。

也就是 Book class 本質還是 constructor function,因此 Book.prototype.constructor 依然指向 Book(),因此回傳 true。
Prototype Chain
class Book {
constructor(title, price) {
this.title = title
this.price = price
}
showDescription() {
return `${this.title} / ${this.price}`
}
}
Book.prototype.getTitle = function() {
return this.title
}
let book = new Book('FP in JavaScript', 100)
book.getTitle() // ?
12 行
Book.prototype.getTitle = function() {
return this.title
}
既然已經證明 class 本質是 constructor function,若對 Book.prototype 新增 getTitle(),ES6 也會依照 prototype chain 找到 getTitle() 正常執行。

Function Call
class Book {
constructor(title, price) {
this.title = title
this.price = price
}
showDescription() {
return `${this.title} / ${this.price}`
}
}
Book.prototype.getTitle = function() {
return this.title
}
let book = Book('FP in JavaScript', 100)
16 行
let book = Book('FP in JavaScript', 100)
Constructor function 仍可被呼叫,只是回傳 undefined 而已,但 class 則完全無法當成 function 被呼叫,直接 syntax error。

Conclusion
- ES6 雖然支援
classkeyword,但 ECMAScript 本質仍是以 object 與 function 為主的語言,class只是 syntatic sugar,讓其他語言背景學習 ECMAScript 時能快速ㄉ上手,但底層仍以 constructor function 與 prototype 實作 class雖然本質是 constructor function,但還是有些不同,如 constructor function 可被直接呼叫,只是回傳undefined而已;但class則完全無法當 function 使用,直接 syntax error
Reference
許國政, 008 天重新認識 JavaScript