JavaScript进阶③|Map_Set_WeakMap_WeakSet,新型数据结构


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 基本用法

javascript 复制代码
// 创建 Set(自动去重)
const set = new Set([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)); // true
console.log(set.has(10)); // false

// 获取大小
console.log(set.size); // 4

// 清空
set.clear();
console.log(set.size); // 0

1.2 Set 的迭代

javascript 复制代码
const set = new Set(["苹果", "香蕉", "橙子"]);

// for...of 遍历
for (const item of set) {
    console.log(item);
}

// forEach 遍历
set.forEach((value, valueAgain, set) => {
    console.log(value); // 注意:value 和 valueAgain 相同
});

// 转数组
const arr = [...set];
console.log(arr); // ["苹果", "香蕉", "橙子"]

1.3 Set 的常见用途

javascript 复制代码
// 1. 数组去重
const arr = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(arr)];
console.log(unique); // [1, 2, 3, 4]

// 2. 求并集
const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);
const union = new Set([...set1, ...set2]);
console.log([...union]); // [1, 2, 3, 4]

// 3. 求交集
const intersection = new Set([...set1].filter(x => set2.has(x)));
console.log([...intersection]); // [2, 3]

// 4. 求差集
const difference = new Set([...set1].filter(x => !set2.has(x)));
console.log([...difference]); // [1]

二、Map(映射)

2.1 基本用法

javascript 复制代码
// 创建 Map
const map = new Map();

// 设置键值对(键可以是任意类型)
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 的区别

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

2.3 Map 的迭代

javascript 复制代码
const map = new Map([
    ["name", "张三"],
    ["age", 25],
    ["city", "北京"]
]);

// for...of 遍历(解构)
for (const [key, value] of map) {
    console.log(`${key}: ${value}`);
}

// forEach 遍历
map.forEach((value, key) => {
    console.log(`${key} = ${value}`);
});

// 只遍历键
for (const key of map.keys()) {
    console.log(key);
}

// 只遍历值
for (const value of map.values()) {
    console.log(value);
}

// 转对象(键需要是字符串)
const obj = Object.fromEntries(map);
console.log(obj); // { name: "张三", age: 25, city: "北京" }

2.4 Map 的初始化

javascript 复制代码
// 方式1:传入二维数组
const map1 = new Map([
    ["name", "张三"],
    ["age", 25]
]);

// 方式2:从对象创建
const obj = { name: "张三", age: 25 };
const map2 = new Map(Object.entries(obj));

// 方式3:从另一个 Map 创建
const map3 = new Map(map1);

三、WeakMap 和 WeakSet

3.1 WeakSet

javascript 复制代码
// WeakSet 只能存储对象,且是弱引用
const weakSet = new WeakSet();
let obj = { 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

javascript 复制代码
// WeakMap 的键只能是对象,值可以是任意类型
const weakMap = new WeakMap();
let key = { id: 1 };

weakMap.set(key, "值1");
console.log(weakMap.get(key)); // "值1"

// 当 key 不再被引用时,键值对会被垃圾回收
key = null; // 现在 weakMap 中的键值对可以被回收了

// 注意:WeakMap 不可迭代,也没有 size 属性
// weakMap.forEach(...); // ❌ 不存在

3.3 使用场景

javascript 复制代码
// 场景1:私有数据(WeakMap)
const privateData = new WeakMap();

class User {
    constructor(name) {
        this.name = name;
        privateData.set(this, { salary: 10000 });
    }
    
    getSalary() {
        return privateData.get(this).salary;
    }
}

const user = new User("张三");
console.log(user.getSalary()); // 10000
// privateData 中的用户数据不会阻止 user 被回收

// 场景2:缓存计算结果(WeakMap)
const cache = new WeakMap();

function process(obj) {
    if (cache.has(obj)) {
        return cache.get(obj);
    }
    const result = /* 复杂计算 */ obj.name + "已处理";
    cache.set(obj, result);
    return result;
}

四、知识卡

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

五、课后作业

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

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


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

相关推荐
cpp_25011 小时前
P11375 [GESP202412 六级] 树上游走
数据结构·c++·算法·题解·洛谷·树形结构·gesp六级
天才程序YUAN1 小时前
Windows 11 C 盘扩容完整教程:恢复分区拦路、页面文件锁盘、WinRE 重建全记录
c语言·开发语言·windows
我是一颗柠檬1 小时前
C语言最全面复习:从入门到精通(2026年)
c语言·开发语言
小雨下雨的雨1 小时前
鸿蒙PC用Electron框架 实现 房产交易系统核心算法深度解析
前端·javascript·算法·华为·electron·鸿蒙系统
ch.ju1 小时前
Java Programming Chapter 4——The set method assigns a value to the property.
java·开发语言
此生决int1 小时前
算法从入门到精通——字符串
数据结构·c++·算法·蓝桥杯
古城小栈1 小时前
Rustix库:Rust 系统编程 的 基石
开发语言·后端·rust
Luminous.1 小时前
C语言--day26
c语言·开发语言
luj_17681 小时前
硝酸体系核关联假说解析
服务器·c语言·开发语言·经验分享·算法