首先,声明一个 map 和 object
const map = new Map()
const object = {}
- 键的数量
- map 默认只会得到显示插入的键
- object 会获得原型链上额外的键
map.size // 0
Object.setPrototypeOf(object, {
foo: '123'
})
let keyCount = 0
for(let i in object) {
keyCount ++
}
keyCount // 1
- 键的类型
- map 的键可以是任意值
- object 的键必须是字符串或 Symbol,否则会被转为字符串,转化的方式是调用值身上的 toString 方法
const a = () => {}
const b = {}
const c = '1234'
const d = Symbol('key-d')
map.set(a, 'key a')
map.set(b, 'key b')
map.set(c, 'key c')
map.set(d, 'key d')
console.log(map.size)
// 4
object[a] = 'key a'
object[b] = 'key b'
object[c] = 'key c'
object[d] = 'key d'
console.log(object)
// {
// '1234': 'key c',
// '() => {}': 'key a',
// '[object Object]': 'key b',
// [Symbol(key-d)]: 'key d'
// }
- 键的顺序
- map 的 key 是有序的。迭代时,以插入的顺序迭代
- object 的键是无序的
for(let key of map.keys()) {
console.log(key)
}
// [Function: a]
// {}
// 1234
// Symbol(key-d)
for(let key in object) {
console.log(key)
}
// 1234
// () => {}
// [object Object]
// foo
- 获取键的数量
- map 通过 map.size
- object 需要手动计算
map.size // 4
// 手动计算 object key 数量
function getObjectkeyNum(o) {
let keyNum = 0
for(let i in o) {
keyNum ++
}
return keyNum
}
- 迭代
- map 是 iterable,key for...of,或者调用自身 keys 方法
- object 只能 for...in,或者使用 Object.keys 方法等
for(let [key, val] of map) {
console.log(key, val)
}
-
性能上
- 当key为有序连续的整数时,Object的性能优于Map;(V8对Object在键为有序连续正整数时做了优化)
- 当key为字符串、非有序连续整数、Symbol时Map的 添加 和 读取 性能优于Object,修改 和 删除 操作性能相差不大;(Object会把键转为String类型,消耗了一部分性能)
- 当key为其他数据类型时,只能选择Map;(Object的键只能为string、symbol类型)