美文网首页
阮一峰ES6教程读书笔记(十)Map数据结构

阮一峰ES6教程读书笔记(十)Map数据结构

作者: 前端艾希 | 来源:发表于2019-10-15 20:58 被阅读0次

    致自己

    自从工作后很久没有看书也没有更文了,因为开发任务重并且逻辑极其复杂,每天回家后什么都不想干了,但是,每天脑海中都有一个声音在提醒我,不能就这样下去,否则终将被时代淘汰。

    做技术的核心就在于学习,不断的学习,只有这样才能立于潮头而不会被拍在沙滩上,所以我只能自己鞭策自己向前赶,加油!

    Map

    1. Map的含义和基本用法

    在出现Map之前,我们一直使用Object来存储键值对组合,但是这样有一个很大的弊端就是,key-value组合的key必须是字符串,如果不是字符串则会被强制转为字符串:

    const data = {};
    const element = document.getElementsByTagName('div')
    
    data[element] = 'metadata';
    data['[object HTMLDivElement]'] // "metadata"
    
    element.toString() // "[object HTMLCollection]"
    

    通过上面的代码我们可以看出当我们想用一个DOM节点来当做对象的key的时候,系统会先调用keytoString()方法,那么这样就会使我们在使用Object数据结构来做key-value存储时带来了一些风险,因为有时我们可能对keytoString()并不太了解。所以我们需要使用一种能够使用任何值作为key或者value的数据结构。

    cosnt m = new Map()
    const key = {name: 'bing'}
    
    m.set(key, 111)
    m.has(key) // true
    m.get(key) // 111
    m.size // 1
    

    上面的代码展示了Map的一般用法,Map构造函数接受一个数组生成Map数据结构。

    let arr = [['name', 'bing'], ['age', 23]]
    
    let map = new Map(arr)
    // 等价于
    arr.forEach([key, value] => {
        map.set(key, value)
    })
    

    其实,不仅仅是数组,任何成员是一个双元素对并且具有Iterator接口数据结构都能生成Map数据结构,比如使用Set

    注意:

    • 如果使用set方法连续对两个相同的键赋值。那么后面的值会覆盖掉前面的值。
    • 如果使用get读取一个位置的键值,那么返回undefined
    • 如果setkey是一个对象,那么必须是对同一个对象的引用才能被视作同一个键,即这里看得是内存地址。

    2.Map 的实例属性和方法

    2.1 size属性

    size返回Map的成员总数

    2.2 Map.prototype.set(key, value)

    set方法设置键名key对应的键值为value,然后返回整个Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。

    2.3 Map.prototpye.get(key)

    使用getMap中取键为key的值

    2.4 Map.prototype.has(key)

    判断该Map结构中是否有含有该key的键值对,该方法返回一个布尔值来表示是否存在

    2.5 Map.prototype.delete(key)

    delete方法用来删除某个键,如果成功就返回true失败返回false

    const map = new Map([['name', 'bing'], ['age', 23]])
    
    map.delete('name') // true
    map.delete('name') // false
    

    可以看到,如果这个键不存在与该Map结构中,如果使用删除操作也是会被判定失败的。

    2.6 Map.prototype.clear()

    清除Map中所有的值,该方法没有返回值。

    3. Map的遍历操作

    Map提供3个遍历器生辰函数和一个遍历方法:

    • Map.prototype.keys():返回键名的遍历器。
    • Map.prototype.values():返回键值的遍历器。
    • Map.prototype.entries():返回所有成员的遍历器。
    • Map.prototype.forEach():遍历 Map 的所有成员。

    值得注意的是,返回遍历器的元素的顺序就是Map插入元素的顺序

    let map = new Map()
    
    map.set('name', 'bing')
    map.set('age', 23)
    
    for (let [key, value] of map.entries()) {
        console.log(key, value)
    }
    // name bing
    // age 23
    
    for (let [key, value] of map) {
        console.log(key, value)
    }
    // name bing
    // age 23
    

    通过上面的代码可以看出MapIterator接口默认就是entries方法

    4. 关于Map的编程技巧

    4.1

    Map本身不具备数组的遍历方法,除了forEach,这时候我们可以通过扩展运算符将Map快速转成Array,然后调用数组的遍历方法,操作完之后再使用构造函数Map()将其转为Map

    4.2

    MapforEach方法可以接受第二个参数来绑定this,这样我们就可以在forEach的函数作用域内来对this绑定的对象进行操作,例如:

    let map = new Map()
    map.set('name', 'bing')
    map.set('age', 23)
    
    let person = {}
    map.forEach(function(key, value){
        this[key] = value
    }, person)
    
    person // {23: "age", bing: "name"}
    

    请注意keyvalue的位置,这里很容易形成误导。

    值得注意的是,这里可能会有人犯一个非常小的错误,就是我们可能在平时开发中经常使用箭头函数,在这里我们如果将传入forrrEach的方法使用箭头函数定义了,那么函数将不能正常执行,因为箭头函数会绑定this为其定义时的环境。一般情况下,这里的this都会是Window

    let map = new Map()
    map.set('name', 'bing')
    map.set('age', 23)
    
    let person = {}
    map.forEach((value, key) => {
        this[key] = value
    }, person)
    
    person // {}
    
    window.name // "bing" 
    window.age // 23
    

    4.3 ArrayMap

    可以通过构造函数很方便地将数组转为Map

    let arr = [['name', 'bing']]
    const map = new Map(arr)
    
    map // {"name" => "bing"}
    

    4.4 Map转为Array

    使用扩展运算符能够很方便的将Map转为Array

    let map = new Map().set('name', 'bing')
    let arr = [...map]
    
    arr // ["name", "bing"]
    

    4.5 MapObject的相互转换

    这两种数据结构之间的相互转换主要依靠遍历,然后调用赋值语句或者Mapset方法。

    4.6 Map 转为 JSON

    分两种情况讨论,如果Map的键名都是字符串,那么我们可以先把Map转为对象,然后再转为JSON,其次,如果Map的键有的不是字符串,那么我们可以考虑将其转为数组,然后再将其转为JSON,这样的话,我们就可以保留特殊键。

    参考链接

    作者:阮一峰
    连接:http://es6.ruanyifeng.com/#docs/set-map

    相关文章

      网友评论

          本文标题:阮一峰ES6教程读书笔记(十)Map数据结构

          本文链接:https://www.haomeiwen.com/subject/jvdemctx.html