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+
相关文章
相关标签/搜索