ECMAScript 2015 除了支援一般 OOP 都有的 Class Declaration 外,還繼承了 ECMAScript 傳統,另外提供了 Class Expression,這使得根據條件動態建立 Class 成為可能。
Version
macOS Catalina 10.15.2
VS Code 1.41.1
Quokka 1.0.267
ECMAScript 2015
Class Declaration
class Book {
constructor(name, price) {
this.name = name
this.price = price
}
}
let book = new Book('FP in JavaScript', 100)
book.name // ?
ES6 支援了 class declaration,這使得使用 ECMAScript 也能使用一般 OOP 的 class。
但若要根據條件建立不同 class,使用 class declaration 無法實現。
Constructor Function
let fn = str => {
let Book = function(name, price) {
this.name = name
this.price = price
}
let Student = function(name, gender) {
this.name = name
this.gender = gender
}
return (str === 'Book') ? Book : Student
}
let class_ = fn('Book')
let foo = new class_('FP in JavaScript', 100)
foo.name // ?
若 fn()
要根據 argument 回傳不同 class,因為 ECMAScript 支援 first-class function,因此我們可改由 constructor function 建立 class,然後根據條件回傳。
Class Expression
let fn = str => {
let Book = class {
constructor(name, price) {
this.name = name
this.price = price
}
}
let Student = class {
constructor(name, gender) {
this.name = name
this.gender = gender
}
}
return (str === 'Book') ? Book : Student
}
let class_ = fn('Book')
let foo = new class_('FP in JavaScript', 100)
foo.name // ?
由於 ES6 支援 class expression,因此 constructor function 可用 class expression 改寫,如此 fn()
亦可根據 argument 回傳不同 class。
Conclusion
- 讓 class 也成為 expression 是很有創意寫法,這使得 ECMAScript 可不必使用 conditional compilation 就能根據條件動態建立 class
- 不過 constructor function 寫法比較精簡,而且回傳 constructor function 也天經地義,畢竟 first-class function 能 return 很正常;但要能回傳 class 就比較特別,除非支援 class expression