// Map 可以使用任何 JS 数据类型作为键, 映射的值没有限制
// 使用 new Map() 创建一个空映射
const m1 = new Map()
// 创建并初始化
const m2 = new Map([
['key1', 'val1']
])
// 设置键值对 set() 方法可以链式调用
m2.set('key2', 'val2')
// console.log(m2) // Map(2) { 'key1' => 'val1', 'key2' => 'val2' }
// 获取键的值
// console.log(m2.get('key2')) // val2
// 获取映射中键/值的数量
// console.log(m2.size) // 2
// 删除映射中某一个键
m2.delete('key2')
// console.log(m2) // Map(1) { 'key1' => 'val1' }
// 清空映射
m2.clear()
//console.log(m2) // Map(0) {}
// 映射中的值为引用类型的数据时, 自己的内容被修改, 获取该键的值不会改变
const m3Kye1 = {}
const m3 = new Map()
m3.set(m3Kye1, 'val1')
// console.log(m3.get(m3Kye1)) // val1
m3Kye1.name = 'map test'
// console.log(m3.get(m3Kye1)) // val1
// 顺序与迭代
// 与 Object 类型的主要差异是, Map 实例会维护键值对的插入顺序, 因此可根据出入顺序执行迭代操作
// 映射实例提供一个迭代器(Iterator) 能以插入顺序生成[key, value]形式的数组
// 可通过 entries() 方法(或Symbol.iterator属性, 它引用 entries() 取得这个迭代器)
// 通俗点就是: 该映射对象通过调用 entries() 方法可进行遍历
const m4 = new Map([
['key1', 'val1'],
['key2', 'val2']
])
// 一下 方式1 与 方式2 等价
// 方式1
/* for (let mItem of m4.entries()) {
console.log('mItem', mItem)
// mItem [ 'key1', 'val1' ]
// mItem [ 'key2', 'val2' ]
} */
// 方式2
for (let mItem of m4[Symbol.iterator]()) {
// console.log('mItem', mItem)
// mItem [ 'key1', 'val1' ]
// mItem [ 'key2', 'val2' ]
}
// 因为 entires() 是默认迭代器, 所以可以直接对映射实例使用扩展操作, 把映射转为数组
// console.log([...m4]) // [ [ 'key1', 'val1' ], [ 'key2', 'val2' ] ]
// keys(), values() 方法 返回以插入顺序生成键和值的迭代器
for (let keys of m4.keys()) {
// console.log('keys:', keys)
// keys: key1
// keys: key2
}
// 映射的键和值在迭代器遍历时是可以修改的, 但映射内部的引用规则无法修改
// 不妨碍修改作为键或值的对象内部的属性, 因为这样并不影响他们在映射实例中的身份
// 键为 基本类型
const m5 = new Map([
['key1', 'val1']
])
for (let key of m5.keys()) {
// 但此处不会修改 映射 m5 键的值 因为 key 是基本类型
key = 'newKey'
// console.log('changed key:', key)
// console.log('value:', m5.get('key1'))
// changed key: newKey
// value: val1
}
// console.log(m5) //{ 'key1' => 'val1' }
// 键为引用类型
const keyObj = {}
const m6 = new Map([
[keyObj, '引用类型作为键的值']
])
for (let key of m6.keys()) {
// 在此处改变了 key 的值, 在映射中对应的键也会改变
key.name = 'newName'
console.log('key', key) // key { name: 'newName' }
console.log('value:', m6.get(keyObj)) // value: 引用类型作为键的值
}
console.log(m6) // Map(1) { { name: 'newName' } => '引用类型作为键的值' }
// Object 和 Map 的差别
// 1. 内存占用: 若给定固定大小的内存, Map 大约可以比 Object 多存储 50% 的键值对
// 2. 插入性能: 向 Object 和 Map 中插入新键/值的消耗大致相当, 如果代码大量设计大量插入, Map 的性能更佳
// 3. 查找速度: 若都只包含少量键值对, Object 有时候更快
// 若把 Object 当伪数组使用, 键为0,1,2~, 浏览器可进行优化, 在内存中使用更高效的布局大量查找操作, 某些情况, 选择Object 更佳
// 4. 删除性能: Map 的 delete() 操作比插入和查找更快, 若涉及大量操作, 选择 Map
扎实下基础 Map, 做点笔记
最新推荐文章于 2024-09-04 02:27:32 发布