阅读 176

ES6之WaekMap和WeakSet

WeakMap

ECMAScript 6 新增的“弱映射”(WeakMap)是一种新的集合类型,为这门语言带来了增强的键/值对存储机制。WeakMap 是 Map 的“兄弟”类型,其 API 也是 Map 的子集。WeakMap 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱映射”中键的方式

基本API

可以使用 new 关键字实例化一个空的 WeakMap:

const wm = new WeakMap()

弱映射中的键只能是 Object 或者继承自 Object 的类型,尝试使用非对象设置键会抛出TypeError。值的类型没有限制。如果想在初始化时填充弱映射,则构造函数可以接收一个可迭代对象,其中需要包含键/值对数组。可迭代对象中的每个键/值都会按照迭代顺序插入新实例中:

const key1 = {id: 1}, key2 = {id: 2}, key3 = {id: 3}; // 使用嵌套数组初始化弱映射 const wm1 = new WeakMap([ [key1, "val1"], [key2, "val2"], [key3, "val3"] ]); alert(wm1.get(key1)); // val1 alert(wm1.get(key2)); // val2 alert(wm1.get(key3)); // val3 // 初始化是全有或全无的操作 // 只要有一个键无效就会抛出错误,导致整个初始化失败 const wm2 = new WeakMap([ [key1, "val1"], ["BADKEY", "val2"], [key3, "val3"] ]); // TypeError: Invalid value used as WeakMap key typeof wm2; // ReferenceError: wm2 is not defined // 原始值可以先包装成对象再用作键 const stringKey = new String("key1"); const wm3 = new WeakMap([ stringKey, "val1" ]); alert(wm3.get(stringKey)); // "val1" 复制代码

初始化之后可以使用 set()再添加键/值对,可以使用 get()has()查询,还可以使用delete()删除,方法使用同Map差不多

const hd = new WeakMap(); const arr = ["qdxx"]; //添加操作 hd.set(arr, "xiaoyiya"); //查询操作 console.log(hd.get(arr));  // xiaoyiya console.log(hd.has(arr)); //true //删除操作 hd.delete(arr); //检索判断 console.log(hd.has(arr)); //false 复制代码

弱键

WeakMap 中“weak”表示弱映射的键是“弱弱地拿着”的。意思就是,这些键不属于正式的引用,不会阻止垃圾回收。但要注意的是,弱映射中值的引用可不是“弱弱地拿着”的。只要键存在,键/值对就会存在于映射中,并被当作对值的引用,因此就不会被当作垃圾回收

WakeMap的键名对象不会增加引用计数器,如果一个对象不被引用了会自动删除。

  • 下例当hd删除时内存即清除,因为WeakMap是弱引用不会产生引用计数

  • 当垃圾回收时因为对象被删除,这时WakeMap也就没有记录了

let map = new WeakMap(); let hd = {}; map.set(hd, "qdxx"); hd = null; console.log(map); setTimeout(() => {   console.log(map); }, 10000); 复制代码

WeakSet

ECMAScript 6 新增的“弱集合”(WeakSet)是一种新的集合类型,为这门语言带来了集合数据结构。WeakSet 是 Set 的“兄弟”类型,其 API 也是 Set 的子集。WeakSet 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱集合”中值的方式。

基本API

可以使用 new 关键字实例化一个空的 WeakSet:

const ws = new WeakSet()

弱集合中的值只能是 Object 或者继承自 Object 的类型,尝试使用非对象设置值会抛出 TypeError。如果想在初始化时填充弱集合,则构造函数可以接收一个可迭代对象,其中需要包含有效的值。可迭代对象中的每个值都会按照迭代顺序插入到新实例中:

const val1 = {id: 1},       val2 = {id: 2},       val3 = {id: 3}; // 使用数组初始化弱集合 const ws1 = new WeakSet([val1, val2, val3]); alert(ws1.has(val1)); // true alert(ws1.has(val2)); // true alert(ws1.has(val3)); // true // 初始化是全有或全无的操作 // 只要有一个值无效就会抛出错误,导致整个初始化失败 const ws2 = new WeakSet([val1, "BADVAL", val3]); // TypeError: Invalid value used in WeakSet typeof ws2; // ReferenceError: ws2 is not defined // 原始值可以先包装成对象再用作值 const stringVal = new String("val1"); const ws3 = new WeakSet([stringVal]); alert(ws3.has(stringVal)); // true 复制代码

初始化之后可以使用 add()再添加新值,可以使用 has()查询,还可以使用 delete()删除

const hd = new WeakSet(); const arr = ["qdxx"]; //添加操作 hd.add(arr); console.log(hd.has(arr)); //删除操作 hd.delete(arr); //检索判断 console.log(hd.has(arr)); 复制代码

弱值

WeakSet 中“weak”表示弱集合的值是“弱弱地拿着”的。意思就是,这些值不属于正式的引用,不会阻止垃圾回收。

WeaSet保存的对象不会增加引用计数器,如果一个对象不被引用了会自动删除。

  • 下例中的数组被 arr 引用了,引用计数器+1

  • 数据又添加到了 hd 的WeaSet中,引用计数还是1

  • 当 arr 设置为null时,引用计数-1 此时对象引用为0

  • 当垃圾回收时对象被删除,这时WakeSet也就没有记录了

const hd = new WeakSet(); let arr = ["qdxx"]; hd.add(arr); console.log(hd.has(arr)); arr = null; console.log(hd); //WeakSet {Array(1)} setTimeout(() => {   console.log(hd); //WeakSet {} }, 10000);

 伪原创工具 SEO网站优化  https://www.237it.com/ 

作者:小亦呀
链接:https://juejin.cn/post/7035994197651881991


文章分类
前端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐