JavaScript进阶③|Map_Set_WeakMap_WeakSet,新型数据结构
2026/6/4 17:10:49 网站建设 项目流程

author: 专注前端开发,分享JavaScript干货
title: JavaScript进阶③|Map_Set_WeakMap_WeakSet,新型数据结构
update: 2026-04-28
tags: JavaScript,Map,Set,WeakMap,WeakSet,数据结构,ES6,前端进阶

作者:专注前端开发,分享JavaScript干货
更新时间:2026年4月
适合人群:掌握ES6基础,想了解新型数据结构的开发者


前言:为什么需要 Map 和 Set?

传统对象{}只能用字符串或 Symbol 作为键,数组也不能保证元素唯一。

ES6 的 Map 和 Set 解决了这些问题。


一、Set(集合)

1.1 基本用法

// 创建 Set(自动去重)constset=newSet([1,2,2,3,3,4]);console.log(set);// Set(4) {1, 2, 3, 4}// 添加元素set.add(5);console.log(set);// Set(5) {1, 2, 3, 4, 5}// 删除元素set.delete(3);console.log(set);// Set(4) {1, 2, 4, 5}// 检查是否存在console.log(set.has(2));// trueconsole.log(set.has(10));// false// 获取大小console.log(set.size);// 4// 清空set.clear();console.log(set.size);// 0

1.2 Set 的迭代

constset=newSet(["苹果","香蕉","橙子"]);// for...of 遍历for(constitemofset){console.log(item);}// forEach 遍历set.forEach((value,valueAgain,set)=>{console.log(value);// 注意:value 和 valueAgain 相同});// 转数组constarr=[...set];console.log(arr);// ["苹果", "香蕉", "橙子"]

1.3 Set 的常见用途

// 1. 数组去重constarr=[1,2,2,3,3,3,4];constunique=[...newSet(arr)];console.log(unique);// [1, 2, 3, 4]// 2. 求并集constset1=newSet([1,2,3]);constset2=newSet([2,3,4]);constunion=newSet([...set1,...set2]);console.log([...union]);// [1, 2, 3, 4]// 3. 求交集constintersection=newSet([...set1].filter(x=>set2.has(x)));console.log([...intersection]);// [2, 3]// 4. 求差集constdifference=newSet([...set1].filter(x=>!set2.has(x)));console.log([...difference]);// [1]

二、Map(映射)

2.1 基本用法

// 创建 Mapconstmap=newMap();// 设置键值对(键可以是任意类型)map.set("name","张三");map.set(123,"数字键");map.set(true,"布尔键");map.set({},"对象键");// 获取值console.log(map.get("name"));// "张三"console.log(map.get(123));// "数字键"// 检查键是否存在console.log(map.has("name"));// true// 删除键值对map.delete("name");// 获取大小console.log(map.size);// 3// 清空map.clear();

2.2 Map 与 Object 的区别

特性MapObject
键的类型任意类型字符串或 Symbol
键的顺序插入顺序ES2015+ 保留字符串键的插入顺序
大小size属性需要Object.keys(obj).length
迭代可直接迭代需要先获取键数组
性能频繁增删键值对时更好适合存储固定结构数据

2.3 Map 的迭代

constmap=newMap([["name","张三"],["age",25],["city","北京"]]);// for...of 遍历(解构)for(const[key,value]ofmap){console.log(`${key}:${value}`);}// forEach 遍历map.forEach((value,key)=>{console.log(`${key}=${value}`);});// 只遍历键for(constkeyofmap.keys()){console.log(key);}// 只遍历值for(constvalueofmap.values()){console.log(value);}// 转对象(键需要是字符串)constobj=Object.fromEntries(map);console.log(obj);// { name: "张三", age: 25, city: "北京" }

2.4 Map 的初始化

// 方式1:传入二维数组constmap1=newMap([["name","张三"],["age",25]]);// 方式2:从对象创建constobj={name:"张三",age:25};constmap2=newMap(Object.entries(obj));// 方式3:从另一个 Map 创建constmap3=newMap(map1);

三、WeakMap 和 WeakSet

3.1 WeakSet

// WeakSet 只能存储对象,且是弱引用constweakSet=newWeakSet();letobj={name:"张三"};weakSet.add(obj);console.log(weakSet.has(obj));// true// 当 obj 不再被引用时,会被垃圾回收(WeakSet 中的引用不会影响回收)obj=null;// 现在 weakSet 中的对象可以被回收了// 注意:WeakSet 不可迭代,也没有 size 属性// weakSet.forEach(...); // ❌ 不存在// console.log(weakSet.size); // ❌ 不存在

3.2 WeakMap

// WeakMap 的键只能是对象,值可以是任意类型constweakMap=newWeakMap();letkey={id:1};weakMap.set(key,"值1");console.log(weakMap.get(key));// "值1"// 当 key 不再被引用时,键值对会被垃圾回收key=null;// 现在 weakMap 中的键值对可以被回收了// 注意:WeakMap 不可迭代,也没有 size 属性// weakMap.forEach(...); // ❌ 不存在

3.3 使用场景

// 场景1:私有数据(WeakMap)constprivateData=newWeakMap();classUser{constructor(name){this.name=name;privateData.set(this,{salary:10000});}getSalary(){returnprivateData.get(this).salary;}}constuser=newUser("张三");console.log(user.getSalary());// 10000// privateData 中的用户数据不会阻止 user 被回收// 场景2:缓存计算结果(WeakMap)constcache=newWeakMap();functionprocess(obj){if(cache.has(obj)){returncache.get(obj);}constresult=/* 复杂计算 */obj.name+"已处理";cache.set(obj,result);returnresult;}

四、知识卡

数据结构特点用途
Set元素唯一,任意类型去重、集合运算
Map键值对,键任意类型需要非字符串键的映射
WeakSet弱引用对象集合标记对象、私有数据
WeakMap弱引用键值对缓存、私有属性

五、课后作业

  1. 用 Set 实现数组去重,并统计每个元素出现的次数
  2. 用 Map 实现一个简单的 LRU 缓存(最近最少使用)
  3. 用 WeakMap 存储 DOM 元素的状态(如是否被点击过),不阻止垃圾回收

有问题欢迎评论区留言,大家一起讨论!


标签:JavaScript | Map | Set | WeakMap | WeakSet | 数据结构 | ES6 | 前端进阶

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询