javascript中Set、Map、WeakSet、WeakMap区别
前言
在学习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垃圾回收机制
介绍WeakSet和WeakMap时得先简单的介绍一下垃圾回收机制
什么是垃圾回收机制
搞清楚什么是垃圾回收机制,首先要知道什么是垃圾,所谓的垃圾指的是不再被使用的变量和引用的对象,也有可能是对象直接相互访问,导致的死循环。那么垃圾回收机制就是不停的在寻找这些不再被使用的和不再被引用的变量,将他们清除并且释放内存。
标记清除法
现在大多数浏览器使用的都是标记清除法,当变量在运行环境中被声明时给它添加一个标记,当变量离开运行环境时清除内存并清除标记
引用计数法
当我们在创建对象时,给对象的引用计数加一,对象引用完计数减一,最终当引用计数为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一样是键值的集合,但是它的键必须是对象,并且它的键也是弱引用,所有它也有可能被垃圾回收机制所回收且是不可迭代的
以上就是javascript中Set、Map、WeakSet、WeakMap区别的详细内容,更多关于javascript中Set、Map、WeakSet、WeakMap区别的资料请关注我们其它相关文章!