当前位置: 首页 > 科技观察

ES6中Map和Set数据结构的作用

时间:2023-03-13 17:02:51 科技观察

如果要用一句话来形容的话,我们可以说Set是一种数据结构,叫做集合,Map是一种数据结构,叫做字典。那么什么是集合?什么是字典?集合是一堆无序的、关联的、非重复的记忆结构[在数学中称为元素]的组合。字典是元素的集合。每个元素都有一个字段叫做key,不同元素的key是不同的。它们之间有什么区别?共同点:集合和字典都可以存储唯一值不同点:集合以[value,value]的形式存储元素,字典以[key,value]的形式存储元素背景大多数主流编程语言都有多个内置-数据收集。比如Python有列表(lists)、元组(tuples)和字典(dictionary),Java有列表(lists)、集合(sets)、队列(queues)。然而JavaScript只有数组(arrays)和对象(object)这两种内置的数据集合,在ES6之前,我们通常使用内置的Object来模拟Map,但是这种方式模拟的map存在一些缺陷,如下:Object的属性键是String或Symbol,这限制了它们成为不同数据类型的键/值对的集合的能力对象具有的许多属性Set定义:Set对象允许您存储任何类型的唯一值,无论是原始值还是对象引用,Set对象是值的集合,您可以按照它们的顺序迭代其元素插入。Set中的元素只会出现一次,即Set中的元素是唯一的。Set本身是一个用于生成Set数据结构的构造函数。基本上使用语法newSet([iterable])接收数组(或其他具有可迭代接口的数据结构),返回一个新的Set对象constset=newSet([1,2,1,2])console.log(set)//{1,2}上面的代码表明Set可以去除数组元素属性和方法属性中的重复size:返回集合中包含的元素个数console.log(newSet([1,2,1,2].size)//2操作方法add(value):向集合中添加一个新项delete(value):从集合中移除一个值has(value):如果集合中存在该值则返回true,否则返回falseclear():删除集合letset=newSet()集合中的所有项。add(1)set.add(2)set.add(2)set.add(3)console.log(set)//{1,2,3}set.has(2)//trueset.delete(2)set.has(2)//falseset.clear()遍历方法keys():返回键名的遍历器values():返回键值的遍历器entries():返回键值的遍历器pairforEach():使用回调函数遍历每个成员letset=newSet([1,2,3,4])//由于set只有键值,没有键名,key()values的行为()完全一样console.log(Array.from(set.keys()))//[1,2,3,4]console.log(Array.from(set.values()))//[1,2,3,4]console.log(Array.from(set.entries()))//[[1,1],[2,2],[3,3],[4,4]]set.forEach((item)=>{console.log(item)})//1,2,3,4应用场景因为Set结构的值是唯一的,所以我们可以很方便的实现如下//数组去重letarr=[1,1,2,3];升etunique=[...newSet(arr)];leta=newSet([1,2,3]);letb=newSet([4,3,2]);//unionletunion=[...newSet([...a,...b])];//[1,2,3,4]//交点letintersect=[...newSet([...a].filter(x=>b.has(x)))];[2,3]//差分letdifference=Array.from(newSet([...a].filter(x=>!b.has(x))));[1]WeakSetWeakSetobject是一些对象值的集合,每个对象值在WeakSet的集合中只能出现一次。WeakSet的出现主要解决了弱引用对象存储的场景。它的结构类似于Set。与Set不同的是,WeakSet只能是对象的集合,不能是任何类型的任意值。对WeakSet集合中对象的引用是弱引用。如果WeakSet中的对象没有其他引用,那么这些对象将被垃圾回收。这也意味着WeakSet中没有存储当前对象的列表。因此,WeakSet是不可枚举的。WeakSet的性质和操作方法与Set一致。不同的是WeakSet没有遍历方法,因为它的成员都是弱引用,随时会消失,遍历机制不能保证成员的存在。我们一直在说弱引用,那么弱引用到底是什么意思呢?弱引用是指不能确保其引用的对象不会被垃圾收集器回收的引用。换句话说,它可以随时回收。MapMap对象保存键值对,可以记住键的原始插入顺序。任何值(对象或基元)都可以用作键或值。Map对象将根据对象中元素的插入顺序进行迭代—for...of循环将在每次迭代后返回[key,value]形式的数组。基本上,语法newMap([iterable])Iterable可以是数组或其他可迭代对象,其元素是键值对(两个元素的数组,例如:[[1,'one'],[2,'two']]).每个key-valuepair都会添加一个newMapletmap=newMap()map.set('name','vuejs.cn');console.log(map.get('name'))属性和方法基本类似对Set,还有如下方法属性size:返回Map结构的元素总数letmap=newMap()map.set('name','vuejs.cn');console.log(map.size)//1console.log(newMap([['name','vue3js.cn'],['age','18']]).size)//2操作方法set(key,value):添加或更新key-valuepairstotheMapget(key):读取keypair的值,如果没有则返回undefinedhas(key):Map对象中是否有key,否则返回truedelete(key):删除一个key,返回true,删除失败返回falseclear():删除所有元素letmap=newMap()map.set('name','vue3js.cn')map.set('age','18')console.log(map)//地图{"name"=>"vuejs.cn","age"=>"18"}map.get('name')//vue3js.cnmap.has('name')//truemap.delete('name')map.has(name)//falsemap.clear()//Map{}遍历方法keys():返回遍历器ofthekeynamevalues():返回key值的遍历器entries():返回所有成员遍历器forEach():遍历Map的所有成员letmap=newMap()map.set('name','vue3js.cn')map.set('age','18')console.log([...map.keys()])//["name","age"]console.log([...map.values()])//["vue3js.cn","18"]console.log([...map.entries()])//[['name','vue3js.cn'],['age','18']]//namevuejs.cn//age18map.forEach((value,key)=>{console.log(key,value)})应用场景Map会保留所有元素的顺序,yes建立在可迭代的基础上,如果考虑元素迭代或顺序保存或丰富的键值类型,则可以使用它。下面摘录vue3源码中依赖集合的核心实现letdepsMap=targetMap.get(target)if(!depsMap){targetMap.set(target,(depsMap=newMap()))}letdep=depsMap。get(key)if(!dep){depsMap.set(key,(dep=newSet()))}if(!dep.has(activeEffect)){dep.add(activeEffect)activeEffect.deps.push(dep)...}WeakMapWeakMap对象是键/值对的集合,其中的键是弱引用的键必须是对象,值可以是任意的。与Map不同的是Map的key可以是任意类型,而WeakMap的key只能是对象类型的WeakMap键名指向的对象,不包括在垃圾回收机制中。WeakMap的属性和操作方法和Map一样,和WeakSet一样,因为是弱引用,所以WeakSet不会遍历方法类型转换MaptoArray//解构constmap=newMap([[1,1],[2,2],[3,3]])console.log([...map])//[[1,1],[2,2],[3,3]]//Array.from()constmap=newMap([[1,1],[2,2],[3,3]])console.log(Array.from(map))//[[1,1],[2,2],[3,3]]ArrayConverttoMapconstmap=newMap([[1,1],[2,2],[3,3]])console.log(map)//地图{1=>1,2=>2,3=>3}MaptoObject//将非字符串键名转换为字符串函数mapToObj(map){letobj=Object.create(null)for(let[key,value]ofmap){obj[key]=value}returnobj}constmap=newMap().set('name','vue3js.cn').set('age','18')mapToObj(map)//{name:"vue3js.cn",age:"18"}对象转换为Mapletobj={"a":1,"b":2};letmap=newMap(Object.entries(obj))SummarySet,Map,WeakSet,WeakMap都是一个集合数据结构Set,WeakSet是[value,value]的集合,并且是唯一的。Map和WeakMap是[key,value]的集合。Map的key可以是任意类型,WeakMap的key只能是对象类型Set和Map有遍历方法,WeakSet和WeakMap是弱引用,无法遍历