Object 与 Map 的区别
JavaScript 中 Object 和 Map 两种数据结构的对比与使用场景
问题
Object 与 Map 有什么区别?应该如何选择使用?
解答
基本概念
Object 是 JavaScript 中的顶级对象,也是一个构造函数。所有对象都是 Object 的实例,可以通过字面量 {} 或 new Object() 创建。
Map 是 ES6 引入的数据结构,用于解决 Object 只能使用字符串作为键的限制。Map 的键可以是任意类型的值,包括对象、函数等,提供了真正的”值—值”映射。
// Object 创建
const obj = {};
const obj2 = new Object();
// Map 创建
const map = new Map();
主要区别
键的类型
Object 的键只能是字符串、数字或 Symbol,而 Map 的键可以是任意类型:
const obj = {};
obj[{ a: 1 }] = 'value'; // 键会被转为 "[object Object]"
console.log(obj); // { "[object Object]": "value" }
const map = new Map();
map.set({ a: 1 }, 'value'); // 对象可以直接作为键
map.set(function() {}, 'function key'); // 函数也可以作为键
访问方式
// Object
const obj = { name: 'Alice' };
console.log(obj.name); // "Alice"
console.log(obj['name']); // "Alice"
console.log(obj.age); // undefined
// Map
const map = new Map();
map.set('name', 'Alice');
console.log(map.get('name')); // "Alice"
console.log(map.get('age')); // undefined
赋值方式
// Object
obj.name = 'Bob';
obj['age'] = 25;
// Map
map.set('name', 'Bob');
map.set('age', 25);
map.set({ id: 1 }, 'complex key'); // 支持复杂类型的键
删除属性
// Object
const obj = { a: 1 };
delete obj.a; // true
delete obj.b; // true(即使属性不存在也返回 true)
// Map
const map = new Map([['a', 1]]);
map.delete('a'); // true
map.delete('b'); // false(属性不存在返回 false)
获取大小
// Object
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj).length); // 3
console.log(Reflect.ownKeys(obj).length); // 3
// Map
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
console.log(map.size); // 3
迭代方式
// Object(需要转换)
const obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
console.log(key, obj[key]);
}
Object.keys(obj).forEach(key => {
console.log(key, obj[key]);
});
// Map(原生支持迭代)
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (let [key, value] of map) {
console.log(key, value); // 遍历顺序与插入顺序一致
}
map.forEach((value, key) => {
console.log(key, value);
});
使用场景
使用 Object:
- 简单的键值对存储,键为字符串或 Symbol
- 需要 JSON 序列化(
JSON.stringify不支持 Map) - 需要使用对象字面量语法
使用 Map:
- 键需要使用复杂类型(对象、函数等)
- 需要频繁增删操作
- 需要保持插入顺序
- 需要快速获取元素数量
// JSON 序列化示例
const obj = { a: 1, b: 2 };
JSON.stringify(obj); // '{"a":1,"b":2}'
const map = new Map([['a', 1], ['b', 2]]);
JSON.stringify(map); // '{}' (无法正确序列化)
// 需要转换
JSON.stringify(Array.from(map.entries())); // '[["a",1],["b",2]]'
关键点
- Map 的键可以是任意类型,Object 的键只能是字符串、数字或 Symbol
- Map 通过
size属性直接获取大小,Object 需要通过Object.keys()转换 - Map 原生支持迭代器,遍历顺序与插入顺序一致,Object 的遍历顺序不确定
- Map 的
delete方法会返回布尔值表示是否删除成功,Object 的delete操作符即使属性不存在也返回true - Map 不支持 JSON 序列化,需要 JSON 转换的场景只能使用 Object
目录