最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 《javascript高级程序设计》学习笔记 | 6.4.Map

    正文概述 掘金(simon9124)   2021-03-26   568

    Map

    • Map 是 ECMAScript6 的新增特性,是一种新的集合类型,其大多数特性都可以通过 Object 类型实现

    相关代码 →

    基本 API

    • 使用new 关键字Map 构造函数可以创建一个空映射
    const m = new Map()
    console.log(m) // Map(0) {}
    
    • 可以给 Map 构造函数传入一个可迭代对象,需要包含键/值对数组
    // 嵌套数组初始化映射
    const m1 = new Map([
      ['key1', 'val1'],
      ['key2', 'val2'],
      ['key3', 'val3'],
    ])
    console.log(m1) // Map(3) { 'key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3' }
    
    // 自定义迭代器初始化映射
    const m2 = new Map({
      [Symbol.iterator]: function* () {
        yield ['key1', 'val1']
        yield ['key2', 'val2']
        yield ['key3', 'val3']
      },
    })
    console.log(m2) // Map(3) { 'key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3' }
    
    • 初始化后,可以使用set()添加键/值对,使用get()has()进行查询,通过size属性获取映射中的键值对数量,使用delete()clear()删除值
    const m3 = new Map()
    console.log(m3.size) // 0
    
    m.set('firstName', 'Matt').set('lastName', 'Frisbie')
    console.log(m.has('firstName')) // true
    console.log(m.get('firstName')) // 'Matt'
    console.log(m.size) // 2
    
    m.delete('firstName') // 删除这个键值对
    console.log(m.has('firstName')) // false
    console.log(m.get('firstName')) // undefined
    console.log(m.has('lastName')) // true
    console.log(m.size) // 1
    
    m.clear() // 清除所有键值对
    console.log(m.has('firstName')) // false
    console.log(m.has('lastName')) // false
    console.log(m.size) // 0
    
    • set()方法返回映射实例,因此可以把多个操作连缀起来,从初始化到添加键/值对:
    const m4 = new Map().set('key1', 'val1')
    console.log(m4) // Map(1) { 'key1' => 'val1' }
    
    • object只能使用数值、字符串或符号作为键不同,Map可以使用任何 JS 数据类型作为建
    const m5 = new Map()
    
    const functionKey = function () {}
    const symbolKey = Symbol()
    const objectKey = new Object()
    
    m5.set(functionKey, 'functionValue')
      .set(symbolKey, 'symbolValue')
      .set(objectKey, 'objectValue')
    
    console.log(m5.get(functionKey)) // 'functionValue'
    console.log(m5.get(symbolKey)) // 'symbolValue'
    console.log(m5.get(objectKey)) // 'objectValue'
    
    • Object一样,若键或值是对象或其他“集合类型”,当键或值的内容或属性被修改时,映射也受到影响
    const m6 = new Map()
    
    const objKey = {},
      objValue = {},
      arrKey = [],
      arrValue = []
    
    m6.set(objKey, objKey)
    m6.set(arrKey, arrValue)
    console.log(m6) // Map(2) { {} => {}, [] => [] }
    
    objKey.foo = 'foo'
    objValue.bar = 'bar'
    arrKey.push('foo')
    arrValue.push('bar')
    console.log(m6) // Map(2) { { foo: 'foo' } => { foo: 'foo' }, [ 'foo' ] => [ 'bar' ] }
    console.log(m6.get(objKey)) // { foo: 'foo' }
    console.log(m6.get(arrKey)) // [ 'bar' ]
    

    顺序与迭代

    • Object不同,Map维护键值对的插入顺序(Object 是无序的),可以根据插入顺序执行迭代操作
      • 映射实例可以提供一个迭代器Iterator,能以插入顺序生成[key,value]形式的数组
      • 可以通过entries()方法或Symbol.iterator属性取得这个迭代器
    const m7 = new Map([
      ['key1', 'val1'],
      ['key2', 'val2'],
      ['key3', 'val3'],
    ])
    console.log(m7.entries === m7[Symbol.iterator]) // true
    
    for (let pair of m7.entries()) {
      console.log(pair)
      /* 
        [ 'key1', 'val1' ]
        [ 'key2', 'val2' ]
        [ 'key3', 'val3' ]
      */
    }
    for (let pair of m7[Symbol.iterator]()) {
      console.log(pair)
      /* 
        [ 'key1', 'val1' ]
        [ 'key2', 'val2' ]
        [ 'key3', 'val3' ]
      */
    }
    
    • 可以直接对映射实例使用扩展操作,把映射转换成数组
    console.log([...m7]) // [ [ 'key1', 'val1' ], [ 'key2', 'val2' ], [ 'key3', 'val3' ] ]
    console.log(...m7) // [ 'key1', 'val1' ] [ 'key2', 'val2' ] [ 'key3', 'val3' ]
    
    • 如果不使用迭代器,可调用forEach(callBack,opt_thisArg)方法并传入回调,依次迭代每个键值对
      • 回调的第二个可选参数用于重写回调内部 this 的值
    m7.forEach((val, key) => {
      console.log(`${key}->${val}`)
      /* 
        key1->val1
        key2->val2
        key3->val3
      */
    })
    
    • Array的迭代器方法,Mapkeys()values()分别返回以插入顺序生成的键和值的迭代器
    for (let key of m7.keys()) {
      console.log(key)
      /* 
        key1
        key2
        key3
      */
    }
    for (let value of m7.values()) {
      console.log(value)
      /* 
        val1
        val2
        val3
      */
    }
    
    • 迭代器遍历时,键和值均可被修改,不同类型的键或值修改会对映射造成不同影响:
      • 修改原始值的键或值,或重写引用值的键或值,映射内部的引用无法修改,映射不受影响
      • 修改引用值的键或值的属性,映射内部的引用未改变,映射不受影响
    /* 字符串原始值作为键或值 */
    const m8 = new Map([['key1', 'val1']])
    
    for (let key of m8.keys()) {
      key = 'newKey' // 修改键
      console.log(key) // 'newKey'
      console.log(m8.get('key1')) // 'val1',映射内部的引用无法修改
      console.log(m8.get('newKey')) // undefined
      console.log(m8.get(key)) // undefined
    }
    console.log(m8) // Map(1) { 'key1' => 'val1' },映射不受影响
    
    /* 引用值作为键或值 */
    const keyObj = { id: 1 }
    const m9 = new Map([[keyObj, 'val2']])
    
    for (let key of m9.keys()) {
      key.id = 2 // 修改键的属性
      console.log(key) // { id: 2 }
      console.log(m9.get(key)) // val2,映射内部的引用未改变,对象在映射内部仍然引用相同的值
    }
    console.log(m9) // Map(1) { { id: 2 } => 'val2' },映射受影响
    
    for (let key of m9.keys()) {
      key = { id: 3 } // 重写键
      console.log(key) // { id: 3 }
      console.log(m9.get(key)) // undefined,映射内部的引用无法修改
    }
    console.log(m9) // Map(1) { { id: 2 } => 'val2' },映射不受影响
    

    选择 Object 还是 Map

    • 固定大小的内存,Map 约比 Object 多存储 50%的键值对
    • 涉及大量插入操作,Map 性能更佳
    • 涉及大量查找操作,Object 更适合
    • 涉及大量删除操作,毫无疑问选择 Map

    总结 & 问点

    有序
    Object数值、字符串、符号Map任何 JS 数据类型
    • Map 属于什么类型?如何创建 Map 类型?初始化后可以对其进行哪些操作?
    • Map 可以使用哪些数据类型作为键?若键或值是对象,当其内容或属性被修改时,映射受到影响么?
    • Map 和 Object 有哪些区别?
    • 如何将 Map 转换为数组?如何获取 Map 的每一个键值对?单独的键或值呢?
    • 可以在 Map 遍历时修改内部的键或值么?修改后会对 Map 产生影响么?

    起源地下载网 » 《javascript高级程序设计》学习笔记 | 6.4.Map

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元