點燈坊

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

ECMAScript 之 Private Class Field

Sam Xiao's Avatar 2020-11-14

ECMAScript 2015 雖然支援了 Class,但沒支援 Private Field 始終是一大缺憾,目前 Private Field 已經在 Stage 3,在 Node 12+ 與 Vue 皆可使用。

Version

ECMAScript 2020

Value Object Pattern

function Person(name, age) {
  _name = name
  _age = age

  return {
    get name() { return _name },
    get age() { return _age }
  }
}

let person = Person('Sam', 18)
person.name // ?
person.age // ?

ES5 只能使用 function + value object pattern,透過 closure 模擬 private field。

private001

IIFE

let person = ((name, age) => {
  _name = name
  _age = age

  return {
    get name() { return _name },
    get age() { return _age }
  }
})('Sam', 18)

person.name // ?
person.age // ?

也可改用 IIFE 直接回傳 Object,連 Person() 也一併省略。

private002

Private Field

class Person {
  #name = ''
  #age = 0

  constructor(name, age) {
    this.#name = name
    this.#age = age
  }

  get name() {
    return this.#name
  }

  get age() {
    return this.#age
  }
}

let person = new Person('Sam', 18)
person.name // ?
person.age // ?

第 2 行

#name = ''
#age = 0

constructor(name, age) {
  this.#name = name
  this.#age = age
}

在 variable 前加上 # 即成為 private field。

第 10 行

get name() {
  return this.#name
}

get age() {
  return this.#age
}

外界無法直接存取 #name#age,必須透過 nameage getter 才能存取。

private000

Conclusion

  • 若不使用 private class field,藉由 closure 亦可模擬出 OOP encapsulation
  • IIFE 可直接回傳 Object,連 function 都省略
  • Private class field 算 ECMAScript 支援 OOP encapsulation 的重要拼圖,目前已經在 stage 3,即將納入正式規格,由於 Node 12+ 與 Vue 皆已支援,可率先使用

Reference

Dr. Axel Rauschmayer, ES proposal: private methods and accessors in JavaScript classes