js语法---weakMap和weakSet:弱映射和弱集合

关于map和set可以参考:js语法---map,set结构_js .map语法-CSDN博客

weakMap

weakMap是Map的一种,但它有更多的限制,

1. WeakMap 和 Map 的第一个不同点就是,WeakMap 的键必须是对象,不能是原始值(number,string,symbol...)

2. WeakMap 不支持迭代以及 keys()values() 和 entries() 方法。所以没有办法获取 WeakMap 的所有键或值这也表示无法直接获取到weakMap的内部值(打印),

  1. 不可被打印出内容
  2. 不能获取键值
  3. 无法迭代遍历

WeakMap 只有以下的方法:

  • weakMap.get(key) 读取一个值
  • weakMap.set(key, value) 设置一个键值
  • weakMap.delete(key) 删除一个键值
  • weakMap.has(key) 查询键是否存在

        以上这些性质,说明了weakMap可以设置键值,但键必须是对象;不暴露键,没有预知键,就无法拿到对应的值;对weakMap的操作都是基于键,没有键就无法操作weakMap,这相等于拥有很高的保密性;

新建一个weakMap

// 新建一个弱映射
const wMap = new WeakMap();
// 新建一个对象作为弱映射的键
const obj = {
  name: 'John'
};

// obj作为弱映射的键
wMap.set(obj, '这是一个weakMap');

console.log(wMap);
console.log(wMap.get(obj));// 这是一个weakMap

可以看到通过get方法拿到了obj对应的值,而直接打印则没有结果

‘weak’的特性

除了表面用法上的隐私性存值,weakMap还有一个重要的特性,

在JavaScript 引擎中,值在“可达”和可能被使用时,会保持在内存中,否则会被清除;

而对于weakMap,当这个对象存入了weakMap键中,被置空后该对象将会被从内存(和weakMap)中自动清除(节约内存)。

         这个过程就相当于,在一个硬盘中,如果一个文件夹是空文件夹,在不节约空间的情况下(map的环境),空文件夹会被保留,而在节约空间的情况下(weakMap的环境),空文件夹被认为没有作用,被删除。

        这种节省的能力一般会用在第三方库的引用,第三方库常常比较消耗内存,大多数情况下都是使用其一小部分功能,当一个第三方库被使用完后,删除引用它的对象(键),这个第三方库的其他内容也就无法访问到而被删除了

weakSet

和set一样,weakSet也是不重复的值的集合,但是它的值被限制为只能是对象,

  • 与 Set 类似,但是我们只能向 WeakSet 添加对象(而不能是原始值)。
  • 对象只有在其它某个(些)地方能被访问的时候,才能留在 WeakSet 中。
  • 跟 Set 一样,WeakSet 支持 addhas 和 delete 方法,但不支持 size 和 keys(),并且不可迭代。
  1. 只能存对象
  2. 对象没有被使用时,最后会weakSet被删除
  3. 不能被读取值,也不能遍历,只能对其添加,删除和判断

 以上这些性质表示,weakSet可以存值,但不可读取值,只能判断是否有这个值,和删除一个值,

新建一个weakSet

// 新建一个弱集合
const wSet = new WeakSet();
// 新建对象作为弱集合的值
const user1={
  name :'张三'
}
const user2={
  name :'李四'
}
const user3={
  name :'王五'
}
// 将user1,user2作为弱集合的值
wSet.add(user1);
wSet.add(user2);

wSet.has(user1);// true
wSet.has(user3);// false

用户1进入过wSet,可以得到true的判定,用户3则没有被wSet添加,返回了false,

这个特性可以用来表示用户是否访问了网站

一个复杂点的数据结构

// 新建一个弱映射
const wMap = new WeakMap();
// 新建一个映射
const map = new Map();
// 新建一个集合
const set = new Set();
// 新建一个对象作为弱映射的键,同时内容作为映射的值
const obj = {
  name: 'John'
};


set.add(obj);
// 将obj对象的name作为map映射name键的值
map.set(obj.name,set);
// 在将map映射作为wMap映射obj对象的值
wMap.set(obj, map);

console.log('key:\t',obj,'\nvalue:\t',wMap.get(obj));

 

这是一个三层结构,当obj被清除时,后面的map和set都无法被访问了(都被清除),

总结

WeakMap 是类似于 Map 的集合,它仅允许对象作为键,并且一旦通过其他方式无法访问这些对象,垃圾回收便会将这些对象与其关联值一同删除。

WeakSet 是类似于 Set 的集合,它仅存储对象,并且一旦通过其他方式无法访问这些对象,垃圾回收便会将这些对象删除。

它们的主要优点是它们对对象是弱引用,所以被它们引用的对象很容易地被垃圾收集器移除

完整代码展示


// 新建一个弱映射
const wMap = new WeakMap();
// 新建一个对象作为弱映射的键
const obj = {
  name: 'John'
};

// obj作为弱映射的键
wMap.set(obj, '这是一个weakMap');

console.log(wMap);
console.log(wMap.get(obj));// 这是一个weakMap

// 新建一个弱集合
const wSet = new WeakSet();
// 新建对象作为弱集合的值
const user1={
  name :'张三'
}
const user2={
  name :'李四'
}
const user3={
  name :'王五'
}
// 将user1,user2作为弱集合的值
wSet.add(user1);
wSet.add(user2);

console.log(wSet.has(user1));// true
console.log(wSet.has(user3));// false
console.log(wSet);




// // 新建一个弱映射
// const wMap = new WeakMap();
// // 新建一个映射
// const map = new Map();
// // 新建一个集合
// const set = new Set();
// // 新建一个对象作为弱映射的键,同时内容作为映射的值
// const obj = {
//   name: 'John'
// };


// set.add(obj);
// // 将obj对象的name作为map映射name键的值
// map.set(obj.name,set);
// // 在将map映射作为wMap映射obj对象的值
// wMap.set(obj, map);

// console.log('key:\t',obj,'\nvalue:\t',wMap.get(obj));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值