美文网首页web前端
Map和Object的区别

Map和Object的区别

作者: 姜治宇 | 来源:发表于2020-04-18 22:43 被阅读0次

    es6提供了一个Map类,这是新增的一个数据结构,用起来有点像Object,这二者到底有什么区别呢?
    Object本质上是哈希结构的键值对的集合,它只能用字符串、数字或者Symbol等简单数据类型当作键,这就带来了很大的限制。
    比如以下这个例子,我想将dom节点作为键,但是由于对象只接受字符串作为键名,所以键被自动转为字符串[object HTMLDivElement],这显然不是我们想要的。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Map</title>
    </head>
    <body>
        <div id="cont">
    
        </div>
    </body>
    </html>
    <script>
        let cont = document.getElementById('cont')
        let obj = {}
        obj[cont] = 'hello,world'
        console.log(obj)//[object HTMLDivElement]: "hello,world"
    </script>
    

    Map类继承了Object,并对Object功能做了一些拓展,Map的键可以是任意的数据类型。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Map</title>
    </head>
    <body>
        <div id="cont">
    
        </div>
    </body>
    </html>
    <script>
        let cont = document.getElementById('cont')
        let m = new Map()
        m.set(cont, 'hello,world')
        console.log(m)
        console.log(m.get(cont))
    </script>
    

    二者的区别主要有以下几点:

    同名碰撞

    我们知道,对象其实就是在堆开辟了一块内存,其实Map的键存的就是这块内存的地址。只要地址不一样,就是两个不同的键,这就解决了同名属性的碰撞问题,而传统的Object显然做不到这一点。

    let m = new Map()
    m.set({},1)
    m.set({},2)
    m.set({},3) //每一次都是开辟新的堆内存作为键
    console.log(m) //Map { {} => 1, {} => 2, {} => 3 }
    
    let o = {}
    o['a'] = 1
    o['a'] = 2
    o['a'] = 3
    
    console.log(o) //{ a: 3 }
    

    可迭代

    new Map([iterable])
    

    Map实现了迭代器,可用for...of遍历,而Object不行。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Map</title>
    </head>
    <body>
        <div id="cont">
    
        </div>
    </body>
    </html>
    <script>
        let cont = document.getElementById('cont')
        let m = new Map()
        m.set(cont, 'hello,world')//dom对象作为键
        m.set(['username'],'jack')//数组作为键
        m.set(true,1)//boolean类型作为键
        //可以迭代
        for(let val of m){
            console.log(val[0])//key
            console.log(val[1])//value
    
        }
    </script>
    

    长度

    Map可以直接拿到长度,而Object不行。

    let m = new Map()
    m.set({a:1}, 'hello,world')//dom对象作为键
    m.set(['username'],'jack')//数组作为键
    m.set(true,1)//boolean类型作为键
    
    console.log(m.size)//3
    

    有序性

    填入Map的元素,会保持原有的顺序,而Object无法做到。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Map</title>
    </head>
    <body>
        <div id="cont">
    
        </div>
    </body>
    </html>
    <script>
        let cont = document.getElementById('cont')
        let m = new Map()
        m.set(cont, 'hello,world')//dom对象作为键
        m.set(['username'],'jack')//数组作为键
        m.set(true,1)//boolean类型作为键
        //可以保持原有顺序打印
        for(let [key,value] of m){
            console.log(key)
    
        }
    
        let obj = new Object()
        obj['jack'] =  1
        obj[0] = 2
        obj[5] = 3
        obj['tom'] = 4
        //填入Object的元素key是自动按照字符串排序的,数字排在前面
        for(let k in obj){
            console.log(k) // 0 5 jack tom
        }
    </script>
    

    可展开

    Map可以使用省略号语法展开,而Object不行。

    let m = new Map()
    m.set({a:1}, 'hello,world')//dom对象作为键
    m.set(['username'],'jack')//数组作为键
    m.set(true,1)//boolean类型作为键
    
    console.log([...m])//可以展开为二维数组
    
    let obj = new Object()
    obj['jack'] =  1
    obj[0] = 2
    obj[5] = 3
    obj['tom'] = 4
    console.log([...obj])//TypeError: obj is not iterable
    

    相关文章

      网友评论

        本文标题:Map和Object的区别

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