web前端

Map和Object的区别

2020-04-18  本文已影响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
上一篇 下一篇

猜你喜欢

热点阅读