ES6 Map/WeakMap/Set/WeakSet 全解指南

一、设计思想与核心概念

1. 解决传统结构的痛点

  • Object:键只能是字符串/Symbol、无序、无size属性
  • Array:查找效率低(O(n))、无自动去重机制
  • 核心突破
    // 传统方式 vs ES6方式
    const obj = { [{}]: 'value' };  // 键会被转为"[object Object]"
    const map = new Map().set({}, '真实对象键');  // 保留原始键类型
    

2. 四大金刚特性对比

结构键类型值特性可迭代弱引用典型内存消耗(1w条)
Map任意类型任意数据✔️~2.4MB
WeakMap仅对象任意数据✔️~0.7MB
Set-唯一值✔️~1.8MB
WeakSet仅对象唯一对象✔️~0.5MB

二、实例方法与属性详解

1. Map 方法全表

方法/属性语法示例时间复杂度说明
sizemap.sizeO(1)实时条目计数
set(key, value)map.set({id:1}, 'data')O(1)返回Map本身(可链式调用)
get(key)map.get('name')O(1)未找到返回undefined
has(key)map.has(NaN)O(1)返回布尔值
delete(key)map.delete(key)O(1)返回操作是否成功
clear()map.clear()O(n)清空所有条目
keys()for(const k of map.keys())O(n)返回键的迭代器
values()map.values()O(n)返回值的迭代器
entries()map.entries()O(n)返回[key, value]迭代器(默认)
forEach(callback)map.forEach((v,k)=>...)O(n)遍历方法

2. WeakMap 特殊方法

const wm = new WeakMap();
const obj = {};// 仅三个方法可用
wm.set(obj, 'private');  // ✔️
wm.get(obj);             // ✔️
wm.has(obj);             // ✔️
wm.delete(obj);          // ✔️// 以下操作均不支持
wm.size;     // ❌ undefined
wm.clear();  // ❌ 方法不存在
wm.keys();   // ❌ 不可迭代

3. Set 核心方法

方法/属性示例说明
add(value)set.add(100).add(200)链式调用,自动去重
delete(value)set.delete(NaN)返回操作结果
has(value)set.has('test')存在性检测
entries()set.entries()返回[value, value]迭代器

4. WeakSet 方法限制

const ws = new WeakSet();
const obj = {};ws.add(obj);    // ✔️ 仅对象
ws.has(obj);    // ✔️
ws.delete(obj); // ✔️ws.add('str');  // ❌ TypeError
ws.size;        // ❌ undefined

三、使用场景与技巧

1. Map 最佳实践

场景1:DOM节点元数据存储

const nodeMap = new Map();function handleClick(node) {if (!nodeMap.has(node)) {nodeMap.set(node, {clickCount: 0,lastClick: null});}const meta = nodeMap.get(node);meta.clickCount++;meta.lastClick = Date.now();
}

场景2:配置优先级队列

class PriorityQueue {constructor() {this.map = new Map([[1, []], [2, []], [3, []]]);}add(item, priority) {this.map.get(priority).push(item);}process() {for (const [level, tasks] of this.map) {while(tasks.length) {this.execute(tasks.shift());}}}
}

2. WeakMap 高级用法

实现真正私有属性

const privateStore = new WeakMap();class BankAccount {constructor(balance) {privateStore.set(this, {balance: balance,transactions: []});}deposit(amount) {const data = privateStore.get(this);data.balance += amount;data.transactions.push({ type: 'deposit', amount });}get balance() {return privateStore.get(this).balance;}
}

深度克隆辅助

function deepClone(obj, map = new WeakMap()) {if (obj === null || typeof obj !== 'object') return obj;if (map.has(obj)) return map.get(obj);const clone = Array.isArray(obj) ? [] : {};map.set(obj, clone);for (const key in obj) {if (obj.hasOwnProperty(key)) {clone[key] = deepClone(obj[key], map);}}return clone;
}

3. Set 实战技巧

场景:用户权限校验

const ADMIN = Symbol('admin');
const EDITOR = Symbol('editor');const userPermissions = new Set([ADMIN, EDITOR]);function canDeleteContent(user) {return userPermissions.has(ADMIN);
}// 动态权限管理
function updatePermissions(user, perm) {userPermissions.add(perm);
}

高效数组去重

// 传统方式 vs Set方式
const arr = [1,2,2,3,3,3];// O(n^2)
const uniqueArr = arr.filter((v,i) => arr.indexOf(v) === i);// O(n)
const setWay = [...new Set(arr)];

4. WeakSet 特殊应用

防止循环引用

const seen = new WeakSet();function safeStringify(obj) {if (typeof obj === 'object' && obj !== null) {if (seen.has(obj)) throw new Error('循环引用');seen.add(obj);}// ...序列化处理
}

四、性能优化策略

1. 基准测试对比(V8引擎)

操作Map(1e6次)Object(1e6次)差异
插入操作~120ms~95ms-17%
读取操作~65ms~80ms+23%
删除操作~110ms~450ms+309%
迭代操作~200ms~350ms+75%

优化建议

  • 大数据集(>10万条):优先使用Map
  • 频繁删除:必须使用Map
  • 内存敏感:考虑WeakMap/WeakSet

2. 内存管理技巧

// 错误示范:内存泄漏
const cache = new Map();
function processData(data) {cache.set(data.id, data); // 长期持有引用,data无法被GC
}// 正确做法:WeakMap自动清理
const weakCache = new WeakMap();
function processObj(obj) {weakCache.set(obj, Date.now());
}

五、对比总结与决策矩阵

1. 四维对比表

特性MapWeakMapSetWeakSet
键类型AnyObject-Object
值唯一性NoNoYesYes
可序列化YesNoYesNo
垃圾回收强引用弱引用强引用弱引用
迭代能力FullNoneFullNone
典型内存占用较高较低中等最低

2. 场景决策树

需要键值对存储?
├─ 需要非对象键 → Map
├─ 需要内存优化 → WeakMap
└─ 需要简单标记 → Set/WeakSet需要保证元素唯一?
├─ 基本类型 → Set
└─ 对象类型 → WeakSet数据生命周期?
├─ 长期存在 → Map/Set
└─ 临时使用 → WeakMap/WeakSet

3. 综合建议

  • 优先考虑Map:当需要键值对且不确定数据结构时
  • 内存敏感场景:使用Weak系列,如DOM节点关联数据
  • 高性能去重:无脑选择Set替代数组方案
  • 私有数据管理:WeakMap是最佳选择

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法篇-----滑动窗口

1.概念 所谓的滑动窗口,就是我们之前的双指针的一个扩展应用,在上一章中,我们的双指针是相向而行的,而这里的双指针是同向而行的,由于其移动过程中像一个窗口一样来回滑动,时大时小,而且还会来…

1.1探索 LLaMA-Factory:大模型微调的一站式解决方案

探索 LLaMA-Factory:大模型微调的一站式解决方案 引言 在大模型的时代,微调技术是将预训练模型适配到特定任务的关键。LLaMA-Factory 作为一款强大的工具,为开发者提供了便捷且高效的大模型微调解决方案。本文将深入介绍 LLaMA-Factory 的基…

神经网络笔记 - 感知机

一 感知机是什么 感知机(Perceptron)是一种接收输入信号并输出结果的算法。 它根据输入与权重的加权和是否超过某个阈值(threshold),来判断输出0还是1。 二.计算方式 感知机的基本公式如下: X1, X2 : …

Pygame事件处理详解:键盘、鼠标与自定义事件

Pygame事件处理详解:键盘、鼠标与自定义事件 在游戏开发中,玩家的交互是至关重要的。无论是移动角色、触发动作还是暂停游戏,都需要通过各种输入来实现。Pygame作为一个功能强大的Python库,提供了丰富的API来处理这些输入,包括键盘、鼠标以及自定义事件。本文将详细介绍如…

使用 Python 项目管理工具 uv 快速创建 MCP 服务(Cherry Studio、Trae 添加 MCP 服务)

文章目录 下载Traeuv 工具教程参考我的这篇文章创建 uv 项目main.pyCherry Studio 添加 MCP 服务申请 DeepSeek API配置 DeepSeek API调用 MCP 服务 Trae 添加 MCP 服务添加 MCP创建智能体 使用智能体调用 MCP 创建 demo 表查询 demo 表结构信息demo 表插入 2 条测试数据查询 d…

为什么要学习《金刚经》

《金刚经》作为佛教般若经典的核心,以"缘起性空"为思想根基,通过佛陀与须菩提的对话,揭示了破除执著、见真实相的智慧。 以下从核心要义、精髓段落和现实应用三个维度进行解读: 一、核心思想精髓 1. "凡所有相&am…

【MQ篇】RabbitMQ之消费失败重试!

目录 引言:消息不丢是底线,失败了优雅重试是修养!消费失败了,为啥不能老是原地复活?🤔智能重试策略一:本地重试(Spring Retry 的魔法)🏠✨智能重试策略二&…

制作一款打飞机游戏33:碰撞体编辑

我们设置系统的方式使得编辑碰撞检测框(即碰撞盒)并不容易。所以,我们的下一步是扩展我们的编辑器,尤其是精灵编辑器,以便我们能够在编辑器中直接编辑碰撞盒。 编辑碰撞盒 让我们加载Sprite编辑器。例如,这…

Kotlin和JavaScript的对比

Kotlin和JavaScript有一些相似之处,但也存在显著的差异,下面从多个方面为你详细分析: 相似点 1. 语法灵活性 变量声明:二者在变量声明上都较为灵活。在JavaScript里,借助var、let和const可以声明变量。其中&#xf…

生活需要一些思考

总分总 写文章、做事情、写邮件、写信,都是要【总分总】。 先总【因为没人有耐心一上来就看细节,先总结,别人感兴趣才会看分】 然后分【分中包括多个子部分,或子章节、子目标,他们之间层层递进,最终引出最…

JAVA设计模式——(九)工厂模式

JAVA设计模式——(九)工厂模式 介绍理解实现ProductFactory测试泛型扩展 应用 介绍 定义一个工厂类的接口,帮助一个实际对象 创建实例,并让其工厂类的子类决定实例化哪个类。 理解 工厂模式中,必定分为了两部分&…

Java后端接口调用拦截处理:注解与拦截器的实现

在Java开发中,对后端接口调用进行拦截处理是一种常见的需求,通常用于权限验证、Token校验、状态更新等操作。本文将围绕 Spring框架的拦截器(Interceptor)、Spring AOP(面向切面编程) 和 Spring Security 三…

第14讲:科研图表的导出与排版艺术——高质量 PDF、TIFF 输出与投稿规范全攻略!

目录 📘 前言:导出,不只是“保存”! 🎯 一、你需要掌握的导出目标 🖼️ 二、TIFF / PNG 导出规范(适用于投稿) 🧲 三、PDF 矢量图导出(排版首选) 🧩 四、强烈推荐组合:showtext + Cairo 🧷 五、多个图的组合导出技巧 🧪 六、特殊投稿需求处理 �…

对 FormCalc 语言支持较好的 PDF 编辑软件综述

FormCalc是一种专为PDF表单计算设计的脚本语言,主要应用于Adobe生态及SAP相关工具。以下是对FormCalc支持较好的主流软件及其特点: 1. Adobe LiveCycle Designer 作为FormCalc的原生开发环境,LiveCycle Designer提供最佳支持: …

第二阶段:基础加强阶段总体介绍

Java语法的学习笔记 下面放复习的文档链接,如果有需要可以前往下载获取,这个仓库还有关于mysql、hadoop、python等的复习部分,并且每个文档有着对应的代码部分。文章作为复习使用,更多代码内容见链接如下: https://gitee.com/zha…

大前端开发——前端知识渐变分层讲解 利用金字塔原理简化前端知识体系

Web开发基础 核心概念 HTML、CSS和JavaScript:Web开发的三大基石,分别负责结构、样式和行为。 代码管理:随着项目规模扩大,需要将代码拆分成小块,便于维护。 作用域污染:早期所有代码共享全局作用域&…

Mixture-of-Experts(MoE)原理与在DeepSeek中的应用

MoE机制简介 Mixture-of-Experts(MoE,混合专家)是一种“分而治之”的神经网络架构思想。在MoE模型中,存在多个并行的子网络,被称为“专家”。每个专家通常擅长处理特定类型的输入特征或知识片段。而在模型前向计算时,并非激活所有专家参与运算,而是通过一个专门的门控网…

SpringCloud学习笔记

个人学习进度:视频跟敲笔记(12天) 学习视频:尚硅谷微服务速通(7小时左右课程) 资源: 1.pdf:微服务pdf(课程):https://pan.baidu.com/s/1g_TAuBjQ…

【大模型】Coze AI 智能体工作流从配置到使用实战详解

目录 一、前言 二、工作流介绍 2.1 什么是工作流 2.2 工作流与对话流 2.2.1 两者区别 2.3 工作流节点介绍 2.3.1 工作流节点说明 2.3.2 开始节点与结束节点 2.4 工作流入口 2.4.1 自定义智能体入口 2.4.2 从资源库新增工作流 2.5 工作流使用限制 三、工作流配置与使…

Discord多账号注册登录:如何同时管理多个账户?

Discord是许多人、特别是游戏玩家和社区管理者的重要沟通工具。随着用户需求的增长,越来越多的人开始在Discord上注册多个账号进行管理。例如,个人和工作账号的区分,多个游戏社区的参与,或者通过不同的身份进行更灵活的社交互动。…