http://mp.weixin.qq.com/s/X8bbwYk3SAkDQVIe4CuGrg
1.在构造函数作用域中处理数据,还可以在构造函数中对函数进行定义,调用参数中的数据(私有变量)
class Countdown { constructor(counter, action) { Object.assign(this, { dec() { if (counter < 1) return; counter--; if (counter === 0) { action(); } } }); } } > let c = new Countdown(2, () => console.log('DONE')); > c.dec(); > c.dec(); DONE
优点:不会与实例属性的名字出现冲突
缺点:如果其他成员方法也要访问这个属性,就都要定义在构造函数中,这样就不太优雅了
2.使用前缀标记的方式
class Countdown { constructor(counter, action) { this._counter = counter; this._action = action; } dec() { if (this._counter < 1) return; this._counter--; if (this._counter === 0) { this._action(); } }
缺点:数据不够安全
3.通过weakMap将私有数据作为附加数据,添加到实例上
let _counter = new WeakMap(); let _action = new WeakMap(); class Countdown { constructor(counter, action) { _counter.set(this, counter); _action.set(this, action); } dec() { let counter = _counter.get(this); if (counter < 1) return; counter--; _counter.set(this, counter); if (counter === 0) { _action.get(this)(); } } }
4.使用symbol
const _counter = Symbol('counter'); const _action = Symbol('action'); class Countdown { constructor(counter, action) { this[_counter] = counter; this[_action] = action; } dec() { if (this[_counter] < 1) return; this[_counter]--; if (this[_counter] === 0) { this[_action](); } } }
symbol作为一个唯一的标识,但还是可以获取得到:
let c = new Countdown(2, () => console.log('DONE')); console.log(Object.keys(c)); // [] console.log(Reflect.ownKeys(c)); // [Symbol(counter), Symbol(action)]
5.通过var创建私有成员
function myConstructor(message){ //公有属性 this.myMessage = message; //私有属性 var separator = '_'; var myOwner = this; //构造函数内私有方法 function alertMessage(){ alert(myOwner.myMessage); } alertMessage(); this.appendToMessage = function(string){ this.myMessage += separator + string; alertMessage(); } }
6.多个实例共享的私有变量
const Person = function(){ var data = 10; return class{ dec(){ data --; } showData(){ console.log(data) } } }(); var p = new Person(); var p1 = new Person(); p1.dec(); p.showData(); // 9