es6 类的私有属性_ES6里的“私有属性与方法”

大家都知道,基于原型链的JavaScript是不提供“私有属性”与“私有方法”的,你要用私有的话,可以,在构造函数里一口气把私有的都写好,然后公开一些接口作为共有属性与方法。

但如果你这么做,你就不得不舍弃原型链,至少上述公开出来的调用了私有属性与方法的接口是不能写在prototype上的,否则就不是私有了,大家都能用。

至于说为什么不在prototype上写是一个问题,这主要是如果你这个类有多个实例化的话,那么就会有多个方法与属性的实例,浪费开销。

这个情况当然不是一成不变的,在ES6以前,要绕过去,当然是有方法的,比如说做两个Array,一一映射地保存当前类实例与其私有属性及方法,这样写在这个类的prototype上的方法就可以通过查询this来获得私有方法与属性几。

这个方法多少有些绕,而且存在各种问题,其中最头疼的恐怕就是去重(每次添加的时候都要搜索一下)与内存溢出。

这是在ES6下会容易解决,因为你现在可以直接使用Map/WeakMap。

下面就给一个例子,利用WeakMap和Set来做一个事件管理器:

(function (root) {

var mEventPool = new WeakMap();

class EventManager {

constructor () {

var pool = {};

mEventPool.set(this, pool);

}

emit (event, ...args) {

if (event === 'emit' || event === 'hook') return;

var pool = mEventPool.get(this);

if (!pool) return;

pool = pool[event];

if (!pool) return;

pool.forEach((callback) => callback.apply(lifeController, args));

}

hook (event, callback) {

if (event === 'emit' || event === 'hook') return;

var pool = mEventPool.get(this);

if (!pool) return;

if (!pool[event]) {

pool[event] = new Set();

}

pool = pool[event];

if (pool.has(callback)) return;

pool.add(callback);

}

}

root.EventManager = EventManager;

}) (window);

每个实例本身都在mEventPool里注册一个个人的“私有对象”,公开方法可以通过this从mEventPool获取这个私有对象,从而完成公开访问私有。

WeakMap只允许非基础类型的对象作为key,在这里刚好够用。

Set不允许有重复,这是比Array好的地方,用来保存callback(当然,这自然也就要求了同一个callback不能注册多次)。

至于说为什么这里每个EM的pool使用传统的object而不用Map(WeakMap不允许基础类型作为key,所以这里肯定不能用),则是因为在这个情况完全没必要用Map。。。这毕竟也是开销啊。。。

至于说还能怎么玩,这个就大家自己去开脑洞吧。

反正,私有以后,似乎也不是特别有用。。。每一次读写都要从WeakMap里索取对象,这也是开销,这点远不如传统方法来得好——这当然是废话了。

你可能感兴趣的:(es6,类的私有属性)