美文网首页
ES6里的“私有属性与方法”

ES6里的“私有属性与方法”

作者: LostAbaddon | 来源:发表于2016-01-26 20:34 被阅读6523次

    大家都知道,基于原型链的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里的“私有属性与方法”

          本文链接:https://www.haomeiwen.com/subject/ysudkttx.html