JS原生不支持私有變量,這讓前端開發很頭痛,如何實現私有變量對於程序的健壯十分重要。下面就講下私有變量的幾種實現,以及對應的babel插件。前端
主要是講ES6相關的Symbol
和WeakMap
,固然閉包也是能夠實現的,本篇主要講es6的。node
let _method = Symbol('_method');
class Foo {
constructor() {
this[_method]();
}
[_method]() {
// ...
}
}
複製代碼
babel-plugin-private-underscoresios
插件自動處理下劃線開頭的屬性與方法,換成Symbol類型的變量es6
class Foo {
constructor() {
this._method();
}
_method() {
// ...
}
}
複製代碼
const _private = new WeakMap();
class Foo {
constructor() {
_private.set(this, 'foo');
}
getPrivate() {
return _private.get(this);
}
}
let foo = new Foo();
console.log(foo.getPrivate()); // private
複製代碼
咱們使用babel官方的插件@babel/plugin-proposal-private-methods
, 連接。npm
babel官方插件是JS新的私有屬性/方法的提案,在私有屬性、方法前面加上#
來標識。下面是對應的寫法瀏覽器
class Foo {
constructor() {
this.publicField = this.#privateMethod();
}
#privateMethod() {
return 42;
}
}
複製代碼
babel-plugin-transform-private-properties插件的寫法以下:babel
class Private_Property_Class_With_WeakMap {
@Private
p = 'foo'
getP() {
return this.p
}
@Private
private_func () {
console.log('this\'s a private function')
}
}
let ppw = new Private_Property_Class_With_WeakMap()
console.log(ppw.getP()) // => foo
console.log(ppw.p) // => undefined
ppw.private_func() // Error: ppw.private_func is not a function
複製代碼
babel產物可見babel try it out,須要本身手動加下plugin
babel-plugin-transform-private-properties,在右下角Plugins
處添加便可閉包
最後對比下Symbol
與WeakMap
的使用,其實二者都實現了私有,並不想_
只是一個標記而已(感受就像babel
裏的設置爲true
的loose
選項同樣)。 對比兩者的兼容性,感受也沒多大的區別,對IE有兼容性的就打消使用的想法了。 在nodejs上使用倒仍是能夠的。ui
Symbol
的瀏覽器兼容性,來源來自mdnthis
IE | Chrome | Edge | Safari | Android Webview | ios Safari | nodejs |
---|---|---|---|---|---|---|
11+ | 38+ | 12+ | 9+ | 38+ | 9+ | 0.12+ |
WeakMap
的瀏覽器兼容性,來源來自mdn
IE | Chrome | Edge | Safari | Android Webview | ios Safari | nodejs |
---|---|---|---|---|---|---|
11+ | 36+ | 12+ | 8+ | 37+ | 8+ | 0.12+ |