做西式快餐店网站昆明网站建设系统
2026/4/6 7:29:48 网站建设 项目流程
做西式快餐店网站,昆明网站建设系统,建立网站代码,wordpress右边的小工具栏存档搜索在 ES6 之前#xff0c;JavaScript 中用于存储键值对的主要数据结构是对象#xff08;Object#xff09;。但对象存在一些固有的局限性#xff0c;比如键只能是字符串或 Symbol 类型、无法直接获取键值对数量、遍历方式不够灵活等。为了解决这些问题#xff0c;ES6 引入了…在 ES6 之前JavaScript 中用于存储键值对的主要数据结构是对象Object。但对象存在一些固有的局限性比如键只能是字符串或 Symbol 类型、无法直接获取键值对数量、遍历方式不够灵活等。为了解决这些问题ES6 引入了 Map 数据结构它是一种更加强大、灵活的键值对集合。本文将从基础到实战全面解析 Map 的核心知识点帮助你彻底掌握这个实用的工具。一、Map 是什么核心特性速览Map 是 ES6 新增的内置对象用于存储键值对key-value pairs并且允许任何类型的值包括原始类型、对象、函数等作为键key这是它与对象最核心的区别之一。Map 的核心特性总结键的多样性键可以是字符串、数字、布尔值、null、undefined、Symbol、对象、函数等突破了对象键只能是字符串/Symbol 的限制。有序性Map 中的键值对是按照插入顺序排列的遍历的时候会按照插入顺序返回结果而对象在 ES6 之前是无序的ES6 后对象键有一定排序规则但不如 Map 明确。可迭代性Map 本身是可迭代对象可以直接通过 for...of 循环遍历无需像对象那样借助 Object.keys() 等方法。动态获取长度通过 size 属性可以直接获取 Map 中键值对的数量而对象需要通过 Object.keys(obj).length 计算。无原型链干扰Map 没有原型链不会出现像对象那样因原型链上的属性而导致的键名冲突比如 obj.hasOwnProperty() 才能判断自身属性。二、Map 的基本使用创建与初始化创建 Map 实例主要有两种方式通过构造函数直接创建空 Map或者传入可迭代对象如数组初始化 Map。2.1 方式一创建空 Map 并添加键值对使用 Map() 构造函数创建空实例后通过 set() 方法添加键值对。// 创建空 Map const map new Map(); // 添加键值对支持不同类型的键 map.set(name, 张三); // 字符串作为键 map.set(18, 年龄); // 数字作为键 map.set(true, 是否成年); // 布尔值作为键 map.set({ id: 1 }, 用户对象); // 对象作为键 map.set(() hello, 函数作为键); // 函数作为键 console.log(map); // Map(5) { name 张三, 18 年龄, true 是否成年, { id: 1 } 用户对象, [Function (anonymous)] 函数作为键 }2.2 方式二通过可迭代对象初始化Map 构造函数可以接收一个可迭代对象如二维数组作为参数数组中的每个元素是一个包含“键”和“值”的二维数组 [key, value]。// 用二维数组初始化 Map const map new Map([ [name, 李四], [Symbol(id), 1001], // Symbol 作为键 [null, 空值键], [undefined, 未定义键] ]); console.log(map.size); // 4通过 size 属性获取长度 console.log(map.get(name)); // 李四通过 get() 方法获取值三、Map 的核心 API增删改查与遍历Map 提供了一套完善的 API 用于操作键值对和遍历掌握这些 API 是使用 Map 的基础。3.1 操作键值对的核心方法方法作用示例set(key, value)添加/修改键值对键存在则修改值不存在则新增返回 Map 实例可链式调用map.set(age, 20).set(gender, 男)get(key)根据键获取值键不存在则返回 undefinedmap.get(name) // 张三has(key)判断键是否存在返回布尔值map.has(18) // truedelete(key)删除指定键的键值对成功删除返回 true键不存在返回 falsemap.delete(name) // trueclear()清空 Map 中所有键值对无返回值map.clear()3.2 关键属性sizesize 属性用于获取 Map 中键值对的数量注意是属性而非方法不需要加括号。const map new Map([[a, 1], [b, 2]]); console.log(map.size); // 2 map.delete(a); console.log(map.size); // 1 map.clear(); console.log(map.size); // 03.3 遍历 Map 的四种方式Map 是可迭代对象支持四种遍历方式且遍历顺序均为插入顺序。1. 遍历键值对for...of 直接遍历 Map直接遍历 Map 时每次迭代返回的是 [key, value] 形式的数组。const map new Map([[name, 王五], [age, 22]]); for (const [key, value] of map) { console.log(${key}: ${value}); } // 输出 // name: 王五 // age: 222. 遍历键keys() 方法keys() 方法返回一个键的迭代器对象可通过 for...of 遍历。for (const key of map.keys()) { console.log(键, key); } // 输出 // 键 name // 键 age3. 遍历值values() 方法values() 方法返回一个值的迭代器对象可通过 for...of 遍历。for (const value of map.values()) { console.log(值, value); } // 输出 // 值 王五 // 值 224. 遍历键值对forEach() 方法forEach() 方法接收一个回调函数回调参数依次为value值、key键、map当前 Map 实例。map.forEach((value, key, currentMap) { console.log(${key}: ${value}); console.log(currentMap map); // true }); // 输出 // name: 王五 // true // age: 22 // true四、Map 的关键细节你必须知道的“坑”使用 Map 时有一些细节容易出错尤其是键的比较规则和引用类型键的处理。4.1 键的比较规则“SameValueZero” 算法Map 中判断两个键是否相等采用的是 “SameValueZero” 算法与 运算符类似但有两个区别NaN 与 NaN 相等 中 NaN NaN 为 false0 与 -0 相等 中 0 -0 为 true两者一致。const map new Map(); // NaN 作为键多次添加会覆盖 map.set(NaN, 第一个 NaN); map.set(NaN, 第二个 NaN); console.log(map.get(NaN)); // 第二个 NaN // 0 和 -0 视为同一个键 map.set(0, 正零); map.set(-0, 负零); console.log(map.get(0)); // 负零4.2 引用类型键的“引用相等”如果键是引用类型如对象、数组、函数Map 判断键是否相等的依据是引用地址是否相同而非值是否相同。const map new Map(); const obj1 { id: 1 }; const obj2 { id: 1 }; // 虽然 obj1 和 obj2 的值相同但引用地址不同视为两个不同的键 map.set(obj1, 对象1); map.set(obj2, 对象2); console.log(map.get(obj1)); // 对象1 console.log(map.get(obj2)); // 对象2 console.log(map.size); // 2这一点在实际开发中很容易踩坑比如用对象作为键存储数据时必须使用同一个对象引用才能获取到对应的值。五、Map 与 Object、Set 的区别为了更清晰地理解 Map 的定位我们对比它与 Object、Set 的核心区别。5.1 Map vs Object对比项MapObject键的类型任意类型原始值、引用值仅字符串、Symbol、数字会自动转为字符串有序性插入顺序可预测ES6 后有排序规则数字优先、字符串按插入顺序不直观长度获取size 属性直接获取需通过 Object.keys(obj).length 计算遍历方式for...of、forEach 等直接遍历需借助 Object.keys() 等方法遍历自身属性需判断 hasOwnProperty原型链干扰无原型链无干扰有原型链可能存在键名冲突如 toString5.2 Map vs SetSet 也是 ES6 新增的集合类型但与 Map 定位不同Map存储键值对key-value核心是“映射关系”Set存储唯一值value核心是“去重集合”。六、Map 的实际应用场景Map 因其特性在很多场景下比 Object 更合适以下是常见的应用场景6.1 存储多类型键的映射关系当需要用非字符串类型如数字、对象、Symbol作为键时Map 是唯一选择。例如用 DOM 元素作为键存储对应的状态const btnStatus new Map(); const btn1 document.getElementById(btn1); const btn2 document.getElementById(btn2); // 用 DOM 元素作为键存储按钮的禁用状态 btnStatus.set(btn1, false); btnStatus.set(btn2, true); // 后续获取状态 if (btnStatus.get(btn1)) { btn1.disabled true; }6.2 需要保持插入顺序的键值对集合当需要遍历键值对时保持插入顺序如配置项、日志记录Map 比 Object 更可靠。例如存储用户操作日志按操作顺序遍历const operationLog new Map(); // 按操作顺序插入日志 operationLog.set(Date.now(), 用户登录); operationLog.set(Date.now(), 查看商品); operationLog.set(Date.now(), 提交订单); // 按插入顺序遍历日志 for (const [time, action] of operationLog) { console.log([${new Date(time).toLocaleString()}] ${action}); }6.3 频繁增删且需要快速获取长度的场景Map 的 size 属性获取长度是 O(1) 时间复杂度而 Object 需要遍历计算频繁增删时 Map 性能更优。例如购物车商品管理const cart new Map(); // 添加商品 function addToCart(goodsId, name, price) { if (cart.has(goodsId)) { // 已存在则数量1 const goods cart.get(goodsId); cart.set(goodsId, { ...goods, count: goods.count 1 }); } else { cart.set(goodsId, { name, price, count: 1 }); } } // 删除商品 function removeFromCart(goodsId) { cart.delete(goodsId); } // 获取购物车商品数量O(1) 操作 function getCartCount() { return cart.size; }6.4 避免原型链污染的场景当需要存储动态键名且担心与 Object 原型链属性冲突时Map 更安全。例如存储用户输入的键值对用户可能输入“toString”等原型属性名// 用 Object 可能污染原型 const userData {}; userData.toString 恶意值; console.log({}.toString()); // 函数未被污染实际在严格模式或现代环境中会限制但仍有风险 // 用 Map 完全无风险 const safeUserData new Map(); safeUserData.set(toString, 恶意值); console.log(safeUserData.get(toString)); // 恶意值不影响原型七、总结Map 是 ES6 为解决 Object 局限性而设计的键值对集合它支持多类型键、有序性、可迭代性和高效的增删查操作在很多场景下比 Object 更优秀。但 Map 并非完全替代 Object当键仅为字符串且不需要有序性时Object 仍有简洁的语法优势。核心要点回顾Map 支持任意类型键判断键相等用 SameValueZero 算法size 属性获取长度set/get/has/delete/clear 操作键值对四种遍历方式均保持插入顺序适合多类型键、有序性、频繁增删的场景避免原型链污染。掌握 Map 的使用能让你的 JavaScript 代码更灵活、高效尤其是在复杂场景下提升开发效率和代码可靠性。

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

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

立即咨询