es6 新增 WeakMap

WeackMap

const toProxy = new WeackMap()
注意:WeakMap对Key有限制,它必须是Object(Symbol也不行)
weackMap的方法有 delete、get、has、set。以前还有个clear,后来被弃用了。

var map = new Map();
var weakmap = new WeakMap();

(function INIT(){
    var ka = {x: 1};
    var kb = {y: 2};

    map.set(ka, 'ka');
    weakmap.set(kb, 'kb');
})()

map.forEach((val, key) => console.log(key, val))//map可以遍历
// Weakmap. forEach(...) ERROR! //weakmap不能遍历

思考一个很深层的问题,在运行完INIT函数后,还需要在map里保存ka的对象呢?

答案应该是“不保存”:ka和kb的作用域在INIT内,之后我们将无法获取这两个引用,再驻留map里只会产生副作用。但是INIT之后,当遍历map时——map.forEach(…),我们依旧能找到{x: 1},而且除了调用clear方法,我们甚至无法删除这个对象;垃圾回收机制更无法对{x: 1}起作用,久而久之便是内存溢出。

具体原因还是得从Map api中深究。Map api共用了两个数组(一个存放key,一个存放value)。给Map set值时会同时将key和value添加到这两个数组的末尾。从而使得key和value的索引在两个数组中相对应。当从Map取值时,需要遍历所有的key,然后使用索引从存储值的数组中检索出相应的value
这个实现的缺点很大,首先是赋值和搜索的时间复杂度比较大;其次是可能导致内存溢出,因为数组会一直保存每个键值引用,即便是引用早已离开作用域,垃圾回收器也无法回收这些内存。那WeakMap呢?(虽然就它那几个api,引用不存在后,WeakMap确实也没啥可以操作了)。

var WeakMap = function() {
    this.name = '__wm__' + vvid()
};

WeakMap.prototype = {
    set: function(key, value) {
        Object.defineProperty(key, this.name, {
            value: [key, value],
        });
        return this;
    },
    get: function(key) {
        var entry = key[this.name];
        return entry && (entry[0] === key ? entry[1] : undefined);
    },
};

weakmap.set(key, val)事实上是直接通过Object.defineProperty给这个key加了一个新属性——this.name,这就解释了为什么WeakMap的key必需是个Object了。
同理,weakmap.get(key)是从key的该属性里获取了值对象。相比Map,WeakMap持有的只是每个键值对的“弱引用”,不会额外开内存保存键值引用。这意味着在没有其他引用存在时,垃圾回收器能正确处理key指向的内存块。正因为这个特殊的实现,WeakMap的key是不可枚举的,更不用说提供keys()、forEach()这类方法了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值