Map vs Object
Map vs Object
一句话:Map的键可以是任何类型、保证插入顺序、有 size、 能直接遍历;对象的键只能是字符串或 symbol, 而且带着一条原型链。
Object | Map | |
|---|---|---|
| 键的类型 | 字符串 / symbol(数字会被转成字符串) | 任何值,包括对象和函数 |
| 顺序 | 整数键会被排序,其余按插入 | 严格按插入顺序 |
| 大小 | Object.keys(o).length | map.size |
| 遍历 | 要先 Object.entries | 本身可迭代,直接 for…of |
| 原型污染 | 有风险 —— o["toString"]本来就有值 | 没有,Map 是干净的 |
| JSON 序列化 | 直接可以 | 不行,要先转数组 |
怎么选:
- 用 Object:结构固定的记录 (一个用户、一份配置),要 JSON 序列化, 字段名写死在代码里。
- 用 Map:键是动态的、会频繁增删、 数量大、键不是字符串。
会追问:「为什么说对象有原型污染风险?」—— 因为空对象也「有」toString、constructor 这些继承来的键。 拿对象当字典时,if (dict[key]) 遇到用户输入"constructor" 会误判成存在。Map 没这个问题, 非要用对象就 Object.create(null)。
「WeakMap 呢?」—— 键必须是对象, 而且不阻止垃圾回收。 适合给对象挂额外数据又不想造成内存泄漏。
In one line: a Map takes keys of any type, guarantees insertion order, has size, and is iterable on its own; an object’s keys can only be strings or symbols, and it drags a prototype chain along with it.
Object | Map | |
|---|---|---|
| Key types | String / symbol (numbers become strings) | Any value, objects and functions included |
| Order | Integer keys get sorted, the rest are insertion order | Strictly insertion order |
| Size | Object.keys(o).length | map.size |
| Iteration | Needs Object.entries first | Iterable itself — for…of just works |
| Prototype pollution | A risk — o["toString"] already has a value | None; a Map is clean |
| JSON serialisation | Works directly | No — convert to an array first |
How to choose:
- Use an Object for records with a fixed shape (one user, one config), for anything you serialise to JSON, and when the field names are written into the code.
- Use a Map when the keys are dynamic, entries come and go often, there are a lot of them, or the keys are not strings.
Follow-up: “Why is an object a prototype pollution risk?” — because even an empty object “has” inherited keys like toString and constructor. Use an object as a dictionary and if (dict[key]) reports a hit when the user types "constructor". A Map does not have this problem; if you must use an object, build it with Object.create(null).
“And WeakMap?” — its keys must be objects, and it does not hold off garbage collection. Good for hanging extra data on an object without leaking memory.