在早期的 JavaScript 中,Object
是唯一可用的键值对结构,常被当作“字典”使用。随着 ES6 的推出,Map
以更现代化和高性能的形式登场,解决了 Object
在键类型、性能、原型污染等方面的局限。理解两者的异同,不仅能写出更清晰的代码,也能在性能和安全性上获得提升。
基本语法
定义方式
1 2 3 4 5 6
| const obj = { key: 'value' };
const map = new Map(); map.set('key', 'value');
|
常用方法对比
操作 |
Object |
Map |
添加键值对 |
obj[key] = value |
map.set(key, value) |
获取键对应值 |
obj[key] |
map.get(key) |
删除键 |
delete obj[key] |
map.delete(key) |
是否存在键 |
'key' in obj |
map.has(key) |
清空所有键值 |
obj = {} 或手动删除所有键 |
map.clear() |
遍历 |
for...in 或 Object.entries |
map.forEach() 或 for...of |
获取键/值数组 |
Object.keys/values/entries |
map.keys()/values()/entries() |
关键区别
键的类型
键值对的有序性
Object
的键是无序的(虽然现代浏览器有一定顺序表现,但不可靠)。
Map
的键值对是按照插入顺序有序的。
原型链干扰
Object
继承自 Object.prototype
,可能会被污染,例如 obj.toString
。
Map
不继承自 Object.prototype
,更安全地避免了原型链上的冲突。
性能差异
操作 |
Map |
Object |
增删查改性能 |
更快(尤其大量数据) |
较慢 |
小数据量性能 |
相差不大 |
相对略快 |
遍历方式
Object 遍历
1 2 3 4 5 6 7 8
| Object.keys(obj).forEach(key => console.log(key, obj[key]));
for (let key in obj) { if (obj.hasOwnProperty(key)) { console.log(key, obj[key]); } }
|
Map 遍历
1 2 3 4 5
| map.forEach((value, key) => console.log(key, value));
for (let [key, value] of map) { console.log(key, value); }
|
创建 MAP
从数组:
1 2 3 4
| const map = new Map([ ['a', 1], ['b', 2], ]);
|
从对象:
1
| const map = new Map(Object.entries(obj));
|
转回对象:
1
| const obj = Object.fromEntries(map);
|
序列化支持
小结
维度 |
Object |
Map |
键类型 |
字符串或 Symbol |
任意类型 |
有序性 |
否 |
是 |
原型污染风险 |
有 |
无 |
序列化方便 |
是 |
否 |
性能(大量数据) |
较慢 |
较快 |
用法 |
简单语法 |
丰富方法 |
- 如果只是存储一些配置项、接口参数,用
Object
更简单。
- 如果需要更灵活、性能更高、更安全的键值结构,尤其处理大量动态键值时,建议使用
Map
。