點燈坊

失くすものさえない今が強くなるチャンスよ

ECMAScript 之 Class Expression

Sam Xiao's Avatar 2020-01-02

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 無法實現。

class000

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,然後根據條件回傳。

class001

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。

class002

Conclusion

  • 讓 class 也成為 expression 是很有創意寫法,這使得 ECMAScript 可不必使用 conditional compilation 就能根據條件動態建立 class
  • 不過 constructor function 寫法比較精簡,而且回傳 constructor function 也天經地義,畢竟 first-class function 能 return 很正常;但要能回傳 class 就比較特別,除非支援 class expression

Reference

MDN, Class Expression