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