ES6私有變量與babel的愛情碰撞

私有變量

JS原生不支持私有變量,這讓前端開發很頭痛,如何實現私有變量對於程序的健壯十分重要。下面就講下私有變量的幾種實現,以及對應的babel插件。前端

主要是講ES6相關的SymbolWeakMap,固然閉包也是能夠實現的,本篇主要講es6的。node

Symbol

原生實現
let _method = Symbol('_method');
class Foo {
  constructor() {
    this[_method]();
  }
 
  [_method]() {
    // ...
  }
}
複製代碼
babel插件實現

babel-plugin-private-underscoresios

插件自動處理下劃線開頭的屬性與方法,換成Symbol類型的變量es6

class Foo {
  constructor() {
    this._method();
  }
 
  _method() {
    // ...
  }
}
複製代碼

WeakMap

原生實現
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官方的插件@babel/plugin-proposal-private-methods, 連接npm

babel官方插件是JS新的私有屬性/方法的提案,在私有屬性、方法前面加上#來標識。下面是對應的寫法瀏覽器

class Foo {
  constructor() {
    this.publicField = this.#privateMethod();
  }

  #privateMethod() {
    return 42;
  }
}
複製代碼
babel-plugin-transform-private-properties

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處添加便可閉包

Final

最後對比下SymbolWeakMap的使用,其實二者都實現了私有,並不想_只是一個標記而已(感受就像babel裏的設置爲trueloose選項同樣)。 對比兩者的兼容性,感受也沒多大的區別,對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+
相關文章
相關標籤/搜索