

新闻资讯
技术学院Map 是一个键类型不限、保持插入顺序、可遍历且具备原生 size 和迭代器的键值容器;其键支持对象/Symbol/NaN等任意类型,遍历严格按写入顺序,增删性能稳定 O(1),适用于动态映射场景。
Map 是 JavaScript 内置的集合类型,本质是一个键值对(key-value)映射表,但和 {} 普通对象有根本区别:它的键可以是任意类型(函数、对象、Symbol、甚至 null),不强制转为字符串;插入顺序严格保留,遍历时按写入顺序返回;且原生支持 size 属性和迭代器接口。
普通对象的所有键都会被隐式调用 toString() 转成字符串。比如 { [{}]: 1 } 实际变成 { "[object Object]": 1 };多个不同对象当键会互相覆盖。Map 则用 SameValueZero 算法比较键——new Date() 和 new Date() 是两个不同键,NaN 也能正确作为键(普通对象里 NaN 键会被转成 "NaN")。
const obj1 = { id: 1 };
const obj2 = { id: 2 };
const map = new Map();
map.set(obj1, "user A");
map.set(obj2, "user B");
console.log(map.size); // 2 ✅
console.log(map.get(obj1)); // "user A"
const plain = {};
plain[obj1] = "user A";
plain[obj2] = "user B";
console.log(Object.keys(plain).length); // 1 ❌(都是 "[object Object]")
普通对象的属性遍历顺序在 ES2015 后虽已规范(先数字键升序,再插入顺序),但仍有兼容性顾虑;Map 则从设计上就保证「插入即顺序」,且 for...of、keys()、values()、entries() 全部原生支持。更重要的是:频繁 delete + set 操作时,Map 的时间复杂度稳定在 O(1),而普通对象在 V8 中可能触发隐藏类重建或字典模式切换,带来不可预期的性能抖动。
Map.prototype.has(key) 比 key in obj 或 obj.hasOwnProperty(key) 更可靠(不继承、不判原型链)Map 的 clear() 是 O(1),普通对象需遍历 Object.keys() 再 delete,是 O(n)别只看“功能多”,关键看使用模式:
Map
Map 更稳map.size,不用 Object.keys(obj).length
Map 是唯一安全选择{},更轻量、可序列化、工具链友好Map 不是对象的“升级版”,而是解决一类特定问题的工具。很多人一上来就用 Map 替换所有对象,结果发现调试困难(DevTools 显示不如对象直观)、不能用点语法、无法被 JSON.stringify 直接处理——这些都不是缺陷,而是设计取舍。