Set、WeakSet、Map、WeakMap、WeakRef介绍及使用场景

Set、WeakSet、Map、WeakMap、WeakRef 介绍及使用场景


一、Set

1、介绍

①set类似于数组,但成员的数值都是唯一的,无重复的值,可以存储任何类型的数据。
②set只有一个size属性。

const set = new Set([1,2,3]);
console.log(set.size) // 3

③方法:

set.has(1); // true
set.add(4); // {1,2,3,4}
set.delete(4); // true
set.clear(); // 无返回值
set.keys(); // SetIterator {1, 2, 3}
set.values(); // SetIterator {1, 2, 3}
set.entries(); // SetIterator {1 => 1, 2 => 2, 3 => 3}

2、使用场景

①数组去重

let arr = [1, 2, 3, 3]
console.log([...new Set(arr)]); // [1, 2, 3]

②数组转换

const set = new Set([1,2,3]);
console.log(Array.from(set)); // [1, 2, 3]

③取数组的并集/交集

const arr1 = [1,2,3,4,5,6]
const arr2 = [3,4,5,6,7,8]
// 并集
const mergeArr = [...new Set([...arr1,...arr2])] //  [1, 2, 3, 4, 5, 6, 7, 8]
// 交集
const overlapArr = [...new Set(arr1)].filter(item => {
 return new Set(arr2).has(item)
}) // [3, 4, 5, 6]

二、WeakSet

1、介绍

①:weakset是弱集合,成员的数值不能重复,数据类型只能是对象。
②:如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存。
③:适合跟踪对象(例如检查对象是否已处理过)
④:无size属性,不可遍历。
⑤:方法:

const obj1 = { name: "garlic" }
const obj2 = { name: "lily" }
const weakSet= new WeakSet([obj1])
weakSet.add(obj2)
weakSet.delete(obj2) // true
weakSet.has(obj1) // true

2、使用场景

①存储DOM节点,防止移除节点时引起内存泄漏

const disabledElements = new WeakSet(); 
const loginButton = document.querySelector('.login');  // 通过加入对应集合,给这个节点打上“禁用”标签 
disabledElements.add(loginButton);
// 这样,只要 WeakSet 中任何元素从 DOM 树中被删除,垃圾回收程序就可以忽略其存在,而立即释放其内存(假设没有其他地方引用这个对象)。

②weakset对实例的引用,不会被计入内存回收机制,所以删除实例的时候,不用考虑weakset,也不会出现内存泄漏。

// 保证了Foo的实例方法,只能在Foo的实例上调用
const foos = new WeakSet()
class Foo {
  constructor() {
    foos.add(this)
  }
  method () {
    if (!foos.has(this)) {
      throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
    }
  }
}

三、Map

1、介绍

①键值对集合,值—值对应(键可以是任何类型),有size属性。

const map = new Map([
    ['name', 'garlic'],
    ['age', 1],
])
map.size //2

②方法:

map.set("sex","woman"); 
map.get("name"); // "garlic"
map.has("name"); // true
map.delete("name"); // true
map.clear(); // 无返回值 undefined
map.keys(); // MapIterator {'name', 'age'}
map.values(); // MapIterator {'garlic', 1}
map.entries(); // MapIterator {'name' => 'garlic', 'age' => 1} 同for(let i of map)
map.forEach((item, index));

2、Map与Object

①:Map的键可以是任何类型,Object只能是number、string、symbol。
②:固定大小内存,Map比Object多存储50%的键值对。
③:Map适用于大量插入\删除操作,Object适用于大量查找操作。

3、使用场景

①:进行条件判断(如路由跳转)

const map = new Map([
  ["login", "/login"],
  ["403", "/403"],
  ["402", "/402"],
]);
this.$router.push({ path: map.get("login") });
[...map] // map转数组

②:map转数组

const map = new Map([
 ['name', "lily"],
 ['age', 22],
]);
console.log([...map.values()]); // ['lily', 22]

③:map转对象

const map = new Map([
 ['name', "lily"],
 ['age', 12],
]);
function mapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}
mapToObj(map); // {name: "lily", age: 12}

四、WeakMap

1、介绍

①:WeakMap只接受对象作为键名(null除外)。
②:WeakMap的键名所指向的对象,不计入垃圾回收机制。
③:方法:

const wm = new WeakMap([]);
const obj = { name: "lily" };
wm.set(obj, 18); // {{…} => 18}
wm.get(obj); // 18
wm.has(obj); // true
wm.delete(obj); //true

2、使用场景

①:DOM 节点作为键名,在Dom对象上存储数据

let wm = new WeakMap();
let element = document.querySelector(".element");
wm.set(element, "data");
wm.get(elemet); // data

②:实现私有属性

const privateData = new WeakMap()
export default class Student {
  constructor(name, age) {
    privateData.set(this, {name, age})
  }
  getName() {
    return privateData.get(this).name
  }
  getAge() {
    return privateData.get(this).age
  }
}

五、WeakRef

1、介绍

①:直接创建对象的弱引用。

let target = {};
let wr = new WeakRef(target);

②:主要用处就是作为缓存,未被清除时可以从缓存取值,一旦清除缓存就自动失效。
③:方法:
deref():原始对象存在,该方法返回原始对象;原始对象已经被垃圾回收机制清除,该方法返回undefined。

let target = {};
let wr = new WeakRef(target);
let obj = wr.deref();
if (obj) { // 判断原始对象是否已被清除
  // ...
}

快来提出你的意见!!
参考链接:ES6中的Set、WeakSet、Map、WeakMap

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值