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

2019-10-15  本文已影响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

注意:

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插入元素的顺序

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

上一篇下一篇

猜你喜欢

热点阅读