zoukankan      html  css  js  c++  java
  • ES6中Map数据结构学习笔记

    很多东西就是要细细的品读然后做点读书笔记,心理才会踏实…

    Javascript对象本质上就是键值对的集合(Hash结构),但是键只能是字符串,这有一定的限制。

    1
    2
    3
    4
    var d = {}
    var ele = document.body
    d[ele] = 'This is body'
    console.log(d['[object HTMLBodyElement]'])

    上段代码的原意是将DOM节点作为对象d的键,由于对象只接受字符串,所以ele被自动转为[object HTMLBodyElement]

    为了解决这种限制,ES6提供了Map数据结构,类似于对象,但是键的范围不限制于字符串,各类数据类型(包括对象)都可以作为键。

    Map基本用法

    请看代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var m = new Map()
    m.set('hello', 'Hello guys').set(true, 'right').set({a: 1}, {a: 1})

    m.size

    m.get('hello')
    m.has(true)
    m.delete(true)
    m.has(true)

    演示过程如下

    Map构造函数可以接收数组作为参数,该数组的成员是一个个表示键值对的数组,如

    1
    2
    3
    4
    var arr = [ ['name', 'liujiangbei'], ['title', '屌丝男'] ]

    var map = new Map(arr)
    console.log(map) // Map { 'name' => 'liujiangbei', 'title' => '屌丝男' }

    该过程就好比

    1
    2
    3
    var map = new Map()
    var arr = [ ['name', 'liujiangbei'], ['title', '屌丝男'] ]
    arr.forEach(([key, value]) => map.set(key, value))

    另外需要特别注意,只有对同一个对象的引用,Map结构才将其视为同一个key。一定是内存地址是一样的两个值。

    对同一个key进行set,后面的值会覆盖前边的值。

    1
    2
    3
    4
    5
    var m = new Map()
    m.set('123', '123')
    m.set('123', '3456')
    m.get('123')
    // 返回 3456

    Map的键实际上跟内存地址绑定,只要内存不一样,就视为两个key,这就解决了同名属性碰撞的问题,

    如果Map的键是简单类型(数字、字符串、布尔),则只要两个值严格相等,Map就将其视为同一个Key,虽然NaN === NaN为FALSE,但Map将其视为同一Key

    1
    2
    3
    4
    5
    6
    let map = new Map()
    map.set(NaN, 123)
    map.get(NaN) // 123

    map.set(-0, 'Zero')
    map.get(+0) // Zero

    这个地方也要特别注意…

    Map实例属性和方法

    属性和方法

    1. size属性
    2. set(k, v)
    3. get(k)
    4. has(k)
    5. delete(k)
    6. clear()

    遍历方法

    1. keys()
    2. values()
    3. entries()
    4. forEach()
    1
    for (let [k, v] of map.entries) { console.log(k, v) }

    等同于

    1
    for (let [k, v] of map) { console.log(k, v) }

    因为表示Map结构的默认遍历器结构(Symbol.iterator)就是entries方法

    1
    2
    var map = new Map()
    console.log(map[Symbol.iterator] === map.entries)

    forEach()方法

    1
    2
    3
    4
    5
    var obj = {}
    map.forEach(function (key, value, map) {
    // do somethings
    // this 指向 obj 对象
    }, obj)

    Map和Array等数据结构的化学反应

    Map和Array

    前边讲到Map的构造函数接收数组,所以Map和Array之间的转化比较方便,但是也有一些约束。

    大专栏  ES6中Map数据结构学习笔记ap">Array转Map

    1
    2
    3
    var arr = [[1, 'ext', '1'], ['2', 2], [3, '3', 'ext']]
    var map = new Map(arr)
    console.log(map)

    可以看出数组转为Map需要满足,数组的元素为数组或者object。

    Map转Array

    利用扩展运算符...很容易实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var arr = [
    ['1', '111'],
    [2, [122, 122]],
    ['name', 'liujiangbei']
    ]
    var map = new Map(arr)

    var keys = [...map.keys()]
    var values = [...map.values()]
    var entries = [...map.entries()]
    entries === [...map] // false


    利用Array的map和filter方法实现Map的map和filter特性

    Map本身并没有map和filter方法,由于数组和Map转换很方便所以利用数组的map的filter特性从而实现达到map和filter的特性。

    1
    2
    3
    4
    5
    var arr = [[1, '1'], [2, '222'], [3, '333']]
    var map = new Map(arr)

    new Map([...map].filter(([k, v]) => k >= 1))
    new Map([...map].map( ([k, v]) => [k * 2, `Map_${v}`] ))


    Map和Object

    Map转为Object

    如果Map的键全为字符串、数字、bool,则其可以转为对象,键非字符串的会通过.toString()方法转化。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function mapToObj (map) {
    var obj = Object.create(null)
    for (let [k, v] of map) {
    obj[k] = v
    }
    return obj
    }

    var map = new Map( [[1, '1'], [true, true], ['111', '111'], [{1: 1}, 111] ])
    var obj = mapToObj(map)
    console.log(obj)
    console.log(typeof obj.true, obj.true)

    Object转为Map

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function objToMap (obj) {
    let map = new Map()
    for (let k of Object.keys(obj)) {
    map.set(k, obj[k])
    }
    return map
    }

    objToMap({yes: true, no: false, 1: 11})

    Map和JSON

    Map转为JSON

    Map的键都是字符串,这是直接转为对象JSON

    1
    JSON.stringify(mapToObj(obj))

    Map的键有非字符串,这是可选择转为数组JSON

    1
    JSON.stringify([...map])

    JSON转Map

    JSON都是字符串的方式,所以先通过JSON.parse(jsonStr)转为对象,然后通过上边的objToMap即可实现转化

    有一种特殊情况,整个JSON就是一个数组,诶个数组成员又都是有两个成员的数组,他可以一一对应转为Map

    1
    new Map(JSON.parse(jsonStr))

    结束语

    网络上这么多同类型的文章为何我还要多此一举?
    看到的永远是别人的,写下来才是自己的,知易行难,日拱一卒,坚持比什么都重要!这句话送给大家也送给我自己…

  • 相关阅读:
    Automatic Setup of a Humanoid
    SLAM——视觉里程计(一)feature
    JSP和EL和JSTL
    rework-发出你的心声
    bootstrap单选框复选框的使用
    bootstrap输入框组
    vue中改变数组或对象,页面没做出对应的渲染
    bootstrap面板的使用
    bootstrap列表组的使用
    bootstrap表格的使用
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12302247.html
Copyright © 2011-2022 走看看