Skip to content

Map

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者基本类型)都可以作为一个键或一个值。

Map

js
const map = new Map()
const map2 = new Map([
  ['key1', 'value1'],
  ['key2', 'value2']
])
const map3 = new Map(map2)

// 操作
map.set(key, value)
map.get(key)
map.has(key)
map.delete(key)
map.clear()

// 大小
map.size

// 生成
map.keys()
map.values()
map.entries()

// 迭代
mpa.forEach(fn)
for (const [key, value] of map) {
}

Map 与 Object

  1. 额外数据:Map 不包含额外的键,Object 有原型链,可能与现有键冲突;
js
const map = new Map()
const obj = {}
map.get('toString') // undefined
obj.toString // function () {}
  1. 键类型:Map 键可以是任意类型,Object 必须是一个 String 或者 Symbol;
js
const map = new Map()
const obj = {}
const a = { name: '张三' }
const b = { name: '李四' }

// map 保存两个值
map.set(a, a)
map.set(b, b)

// obj 只保存最后一次的 b 值
obj[a] = a
obj[b] = b
  1. 大小计算:Map 大小通过 size 查看,Object 需要手动计算;
js
const map = new Map()
const obj = {}

map.set('name', '张三')
obj.name = '李四'

map.size // 1
Object.keys(obj).length // 1
  1. 迭代方式:Map 可直接通过 for...of,迭代,Object 通过 for...in 迭代,但会受原型链的影响;
js
const map = new Map()
const obj = {}
Object.prototype.extra = '额外数据'

for (const item of map) {
}
for (const item in obj) {
  // extra 会被便利
}
  1. JSON.stringify 序列化:Map 需要自定义 toJSON 函数,Object 可直接被序列化;
js
const map = new Map()
const obj = {}

map.set('name', '张三')
obj.name = '李四'

JSON.stringify(map) // {}
JSON.stringify(obj) // {"name":"李四"}

map.toJSON = function () {
  return Object.fromEntries(this)
}
JSON.stringify(map) // {"name":"李四"}

Map 与 WeakMap

  1. Map 中 key 可以是任意类型,WeakMap 中 key 只能是对象;
  2. Map 可删除 key,WeakMap 不能删除,也无法查看大小;
  3. Map 可迭代,WeakMap 不能;
  4. Map 对 key 持续引用无法回收,WeakMap 对 key 是弱引用,不影响垃圾回收器的工作。
vue
<template>
  <el-button @click="onClick">执行</el-button>
  <el-button @click="onStop">停止</el-button>
</template>

<script setup>
const map = new Map()
const weakmap = new WeakMap()

let timer

function onClick() {
  ;(function () {
    let foo = { foo: 1 }
    let bar = { bar: 2 }

    map.set(foo, 1)
    weakmap.set(bar, 2)
    foo = null
    bar = null
  })()
  onStop()
  timer = setInterval(() => {
    console.log(weakmap)
    console.log(map)
  }, 1000)
}
function onStop() {
  clearInterval(timer)
}
</script>