javascript中Set、Map、WeakSet、WeakMap区别

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

javascript中Set、Map、WeakSet、WeakMap区别

weixin_48727473   2022-12-23 我要评论

前言

在学习vue官方源码解析的过程中,看到了有关这一块的解析,所以跟着学习并且记录一下

Set

之前我对Set的了解还是仅仅停留在数组去重,但是我并没有在项目中用过,深入学习后,发现有时候用这个特性还挺方便的。
介绍Set之前我们先来介绍一下集合,集合是由一群无序的、不重复的元素组成的集合。
Set对象是一个由任意唯一值组成的的集合,这个唯一值可以是基本类型,也可以是引用类型,并且Set是可迭代的。

Set的使用

const set = new Set([1, 2, 3, 4, 5, 6, 5, 6]);
console.log(set);

在这里插入图片描述

运行代码可知Set()方法最终生成的是一个去重过后的类数组结构对象。

属性

返回类数组的元素数量

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

方法

  • add(value): 向集合中添加一个新的项
let set = new Set();
set.add(1);
console.log(set); // set: { 1 }
  • delete(value): 从集合中删除一个值
let set = new Set();
set.add(1);
set.add(2);
set.delete(1);
console.log(set); // set: { 2 }
  • has(value): 如果值在集合中存在,返回ture, 否则返回false
let set = new Set();
set.add(1);
console.log(set.has(1)); // true
console.log(set.has(2)); // false
  • clear(): 移除集合中的所有项
let set = new Set();
set.add(1);
set.add(2);
set.clear();
console.log(set.clear()) // undefined
console.log(set) // {size:0}

遍历方法

因为Set方法返回的数据结构是类数组,所以我们要使用Array,form()去将其转化为数组,也可以用ES6的结构将其转化为数组
因为Set是值的集合,它没有键,只有值,所以遍历键和值是的结果是一样的。

keys(): 返回键名的遍历器

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

values(): 返回键值的遍历器

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

entries(): 返回键值对的遍历器(解构类数组)

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

forEach(): 使用回调函数遍历每个成员

let set = new Set([1, 2, 3, 4]);
set.forEach((item: number) => {
    console.log(item); // 轮流输出1,2,3,4
});

小结

当我们的业务需求中有数组去重时可以用,代码量少

也可以用于去交集并集差集时可以用

// 数组去重
let arr = [1, 2, 3, 4, 5, 5];
let arrSet = [... new Set(arr)]; // [1,2,3,4]

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
    
// 并集
let union = [...new Set([...a, ...b])]; // [1,2,3,4]
    
// 交集
let intersect = [...new Set([...a].filter(x => b.has(x)))]; // [2,3]
    
// 差集
let difference = Array.from(new Set([...a].filter(x => !b.has(x)))); // [1]

JS垃圾回收机制

介绍WeakSetWeakMap时得先简单的介绍一下垃圾回收机制

什么是垃圾回收机制

搞清楚什么是垃圾回收机制,首先要知道什么是垃圾,所谓的垃圾指的是不再被使用的变量和引用的对象,也有可能是对象直接相互访问,导致的死循环。那么垃圾回收机制就是不停的在寻找这些不再被使用的和不再被引用的变量,将他们清除并且释放内存。

标记清除法

现在大多数浏览器使用的都是标记清除法,当变量在运行环境中被声明时给它添加一个标记,当变量离开运行环境时清除内存并清除标记

引用计数法

当我们在创建对象时,给对象的引用计数加一,对象引用完计数减一,最终当引用计数为0时,可被垃圾回收机制回收。

WeakSet

WeakSet是对象的集合,它的成员只能是对象,并且都是弱引用的对象,如何理解弱引用,就是当对象不再被引用时,对象会被垃圾回收机制回收,所以没法确认它的成员数量,所以WeakSet它是不可迭代的,无法使用forEach等方法去遍历。

WeakSet方法

add(value): 向集合中添加一个新的项

const Weakset = new WeakSet();

const a = {};
const b = {};

Weakset.add(a);
Weakset.add(b);
console.log(Weakset);

在这里插入图片描述

delete(value): 从集合中删除一个值

const Weakset = new WeakSet();

const a = {};
const b = {};

Weakset.add(a);
Weakset.add(b);
Weakset.delete(b);
console.log(Weakset);

在这里插入图片描述

has(value) 如果值在集合中存在,返回ture, 否则返回false

const a = {};
const b = {};

Weakset.add(a);
Weakset.add(b);
Weakset.delete(b);
console.log(Weakset.has(a)); // true
console.log(Weakset.has(b)); // false

Map

记得第一次接触Map还是在做算法题的时候,当时第一题用双重for循环的话,时间复杂度为O(n^2),但是用map来处理就变成了O(n),至今印象深刻。Map是由键和值组成的集合,就相当于将key也就是指针存在了栈内存中,通过指针去寻找它的值。并且Map是可迭代的集合,每次迭代后都会返回一个[key,value]的数组。

属性

size 返回集合元素的数量

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log(map.size); // 2

方法

set(key, value): 往Map中设置新的值

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log(map);

在这里插入图片描述

get(key): 通过key去获取它的值,如果拿不到就返回与undefined

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log(map.get('a')); // b
console.log(map.get('c')); // undefined

has(key): 判断当前键是否在当前集合中,返回一个布尔值,存在返回true,不存在则返回false

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log(map.has('a')); // true
console.log(map.has('c')); // false

delete(key): 删除集合中的某个元素,通过key去查找,删除后返回一个布尔值,删除成功返回true,否则返回false

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log(map.delete('a'));
console.log(map);

在这里插入图片描述

5. clear(): 删除集合中的所有元素,没有返回值

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log(map.clear()); // undefined
console.log(map); // {size: 0}

遍历方法

keys():返回的是一个迭代后的对象,其中包含着Map对象所有的键。

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log([...map.keys()]); // ['xiao', 'a']

values():返回的是一个迭代后的对象,其中包含Map对象中所有的值。

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log([...map.values()]); // ['chen', 'b']

entries():返回的是一个迭代后的对象,其中包含Map对象中所有的键值对。

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');
console.log([...map.entries()]); 

在这里插入图片描述

forEach():遍历Map对象的所有成员

let map = new Map();
map.set('xiao', 'chen');
map.set('a', 'b');

map.forEach((value, key) => {
    console.log(key, value);
});
// xiao chen
// a b

WeakMap

WeakMap和Map一样是键值的集合,但是它的键必须是对象,并且它的键也是弱引用,所有它也有可能被垃圾回收机制所回收且是不可迭代的

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们