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);作者:小亦呀
链接:https://juejin.cn/post/7035994197651881991
来源:稀土掘金
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!