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。
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()
也一併省略。
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
,必須透過 name
與 age
getter 才能存取。
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