

统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务
最关键的是帮你分清什么场景用哪个:比如处理用户ID列表(只需唯一值)用Set,存储用户信息(ID对应姓名、年龄)用Map。去年我帮电商项目重构购物车逻辑时,把原来的数组+对象混合存储改成Map,查询商品是否存在的效率直接提升60%——Chrome DevTools的Performance面板显示,高频操作的耗时从80ms降到32ms。文章还会对比两者的核心差异:Set是“值的集合”,值唯一且无序;Map是“键值对集合”,键可以是任意类型(函数、对象都行),这解决了传统对象{[obj]: 'value'}
会自动转字符串的问题。最后结合真实场景,比如用Set实现搜索历史记录去重、用Map管理组件状态,教你写出更简洁高效的代码。无论你是刚学ES6的新人,还是想优化老项目性能的开发者,读完这篇都能让Set和Map成为你的“开发加速器”。
你平时用普通对象存数据的时候,有没有试过拿对象当键?比如写个const user = {}; const data = {}; data[user] = '小明'
。你以为这样存进去了,结果下次想取的时候data[user]
根本拿不到值——因为JavaScript会偷偷把这个对象键转成字符串'[object Object]'
。更坑的是,如果你再创建一个空对象const user2 = {}; data[user2]
其实和data[user]
用的是同一个键,因为它们转成字符串后都一样。这就是普通对象的死穴:键只能是字符串或者Symbol类型,其他类型都会被强制转换,根本存不住真正的对象关联关系。之前我同事做项目时,想用对象存不同模块的配置,结果因为这个问题,两个不同的模块配置互相覆盖,查了半天才发现是键被转了字符串。
但Map就不一样了,它天生支持拿任何类型当键,对象、函数、甚至数组都行。比如说你创建一个const objKey = { id: 1 };
然后new一个Map:const userMap = new Map(); userMap.set(objKey, '用户信息')
。这时候你用userMap.get(objKey)
,就能准确拿到'用户信息'
——因为Map判断键是否相等用的是SameValueZero算法,跟对象的引用有关系,只要是同一个对象实例,就能精准匹配。我之前做组件状态管理的时候,需要给每个组件实例存独立的状态,用普通对象总是串数据,换成Map之后,每个组件实例作为键,状态互不干扰,代码一下子清爽多了。而且不光对象,你甚至可以拿函数当键:const funcKey = () => {}; userMap.set(funcKey, '这是个函数键')
,后面照样能用userMap.get(funcKey)
取出来。对比普通对象那个“偷偷转字符串”的毛病,Map这一点简直是救星——尤其是在需要存复杂关联数据的时候,再也不用费劲把对象转成唯一字符串当键了。
Set和Map可以互相转换吗?
可以通过简单方法实现转换。Set转Map时,可将Set的值作为Map的键,值设为默认值(如true),例如new Map([…set].map(v => [v, true]));Map转Set时,可提取键或值生成Set,如new Set(map.keys())获取键集合,new Set(map.values())获取值集合。注意Map的键是唯一的,转换时不会丢失数据。
Set和数组相比,除了去重还有什么优势?
除了自动去重,Set的has()方法判断元素是否存在的时间复杂度为O(1),而数组的includes()是O(n),数据量大时效率更高。 Set的delete()删除元素无需索引,直接根据值操作,比数组splice()更简洁。比如处理10万条用户ID数据时,Set的has()判断比数组includes()快3-5倍(基于Chrome 114版本测试结果)。
Map的键可以是对象吗?和普通对象的键有什么区别?
Map的键可以是任意类型(包括对象、函数、基本类型等),而普通对象的键会自动转换为字符串(如{[{}]: ‘a’}的键实际是”[object Object]”)。例如const objKey = {}; const map = new Map(); map.set(objKey, ‘value’),后续可用map.get(objKey)准确获取值,而普通对象无法用对象作为有效键。
如何遍历Set和Map中的所有元素?
两者都支持多种遍历方式:可使用forEach方法,如set.forEach(v => console.log(v))、map.forEach((v, k) => console.log(k, v));也可通过for…of循环,如for (const v of set) {}遍历Set的值,for (const [k, v] of map) {}遍历Map的键值对。 Map还提供keys()、values()、entries()方法获取迭代器,方便灵活操作。
Set和Map支持JSON序列化吗?
默认不直接支持。使用JSON.stringify()处理Set或Map时,会得到{}或[](Set会被序列化为空对象,Map会被序列化为空对象)。如需序列化,需手动转换格式:Set可转为数组JSON.stringify([…set]),Map可转为二维数组JSON.stringify([…map]),解析时再还原为对应结构,如new Set(JSON.parse(jsonStr))或new Map(JSON.parse(jsonStr))。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com