“作者:Kyle Cook 网站:Web Dev Simplified Blog 字数:1975 字 (非直译) 阅读: 5 分钟
在日常的业务开发中,以下的代码你是否经常见或经常写呢?
const CURRENCY_MAP = {
'United States': 'USD',
'India': 'Rupee'
}
const currency = CURRENCY_MAP['India']
或者
const CURRENCIES = [
{ name: 'USD', country: 'United States' },
{ name: 'Rupee', country: 'India' }
]
const currency = CURRENCIES.find(c => c.country === 'India').name
以上代码确实没有问题,我们在业务中经常用,但是需要创建键值映射关系时,objects 对象 和 arrays 数组 通常不是最佳选择,这也是 JS Maps 存在的理由,今天我们就来简单的聊一聊 JS Maps 集合对象。
Map 其实是是 JS 中的 Class 类,允许你将值存储在特定的键上,但是与 Objects 对象 有一些主要的区别,这些特质,主要是让 Map 在键值应用上表现的更加出色。
对于 Objects 类型而言,你只能使用字符串作为键的类型(ES6 中也可以是 Symbol 类型),但是 Map 则更宽泛的多,你可以使用任何数据类型作为键,比如你可以使用 object, string, boolean, function 等类型,接下来我们来看看下面两段代码:
const obj = {
a: 'b',
1: 2
}
console.log(Object.keys(obj))
// ["a", "1"]
const map = new Map([
['a', 'b'],
[1, 2],
[{ key: 'value' }, 'obj']
])
console.log(map.keys())
// ["a", 1, { key: "value" }]
创建 map 你需要通过数组的形式进行创建,我们可以通过 map.keys() 方法获取 map 对象的键,以数组的形式返回所有的键。
object 对象 键的顺序是不可靠的,直到 ES6 才对其进行规范(自 ECMAScript 2015 规范以来,对象确实保留了字符串和 Symbol 键的创建顺序;因此,在只有字符串键的对象上进行迭代将按插入顺序产生键),则 Map 对象 则不同,当我们对其进行迭代时,则是按照其插入的键值顺序返回的,这个特性很重要。
相对迭代操作,Maps 相对 objects 更加容易,对象没有内置的迭代方法,需要借助 Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,Maps 则天生具有迭代性,这意味着你可以使用 forEach 方法作用于 Maps 上进行迭代。
获取 objects 的长度并不容易,你需要手动计算,并且比较麻烦。但是 Maps 有个 size 属性,类似 arrays 数组 的 length 属性 能够准确的获取 Maps 键/值对的个数。
由于 Maps 设计的初衷就是为了解决 键/值 查找,因此在频繁的增删 键/值 操作的场景下,Map 的性能会更好,则 objects 则没有在这种频繁操作 键/值 的场景进行优化。
通过上面的介绍,我们已经了解了 Maps 和 objects 的区别,接下来聊聊如何使用 Maps。
在上面的例子中,你也许看到了我们是如何创建 Map 的,Map 是一个 Class 类,需要进行实例化,如果你只实例化,不进行传参的话,则是一个空对象。如果需要填充内容的话,需要往里添加可迭代的对象值,比如数组,第一个是键,第二个是键对应的值。
const emptyMap = new Map()
const map = new Map([
['key', 'value']
])
一旦你创建了 Map,接下来你很有可能需要往里填充 键/值 内容,我们可以使用 set 方法,进行 键/值 设置,如下段代码所示:
const map = new Map()
map.set('key', 'value')
map.set(true, 'boolean')
// "key" => "value"
// true => "boolean"
获取值和设置值一样简单,我们可以通过 get 方法,并且传递一个你想获取键的参数,就能获取对应的值。如果键不存在,则返回 undefined。
const map = new Map()
map.set('key', 'value')
map.set(true, 'boolean')
map.get('key')
// "value"
map.get(true)
// "boolean"
map.get('wrong-key')
// undefined
有时你需要查看 Map 对应的键是否存在,你可以使用 has 方法 检查对应的键是否存在。
const map = new Map()
map.set(1, 'number')
map.has(1)
// true
map.has('1')
// false
map.has('wrong-key')
// false
您可能会注意到,检查键时,字符串”1“将返回 false。这是因为 Map 可以存储任何类型,所以数字 1 存储为数字而不是字符串。
增删改查是我们最常见的业务操作,如果你要进行删除操作,同样对于 Map 也十分简单,我们可以使用 delete 方法传递你要删除的键。
const map = new Map()
map.set(1, 'number')
map.set('a', 'b')
map.delete(1)
map.has(1)
// false
有很多方法可以迭代遍历 Map,但是最常见的方法就是通过 forEach 方法 进行迭代。类似数组的 forEach 方法,但是这个回调方法里,含有两个参数,一个表示值,一个表示键。
const map = new Map()
map.set(1, 'number')
map.set('a', 'b')
map.forEach((value, key) => {
console.log(`${key} => ${value}`)
})
// 1 => number
// a => b
Maps 是一个很棒的数据类型,当我们需要频繁使用键值字典查找操作时,是一个不错的选择。今天的内容就到这里,感谢你的阅读。