扎实下基础 Map, 做点笔记

// 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值