作者:Kyle Cook 网站:Web Dev Simplified Blog 本文共 1000 字 (非直译) 阅读需要 3 分钟
在日常的业务开发中,以下的代码你是否经常见或经常写呢?
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 Map对象 存在的理由,今天我们就来简单的聊一聊JS Map 。
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 是一个很棒的数据类型,当我们需要频繁使用键值字典查找操作时,是一个不错的选择。今天的内容就到这里,感谢你的阅读。
注:本文属于原创文章,版权属于「前端达人」公众号及 qianduandaren.com 所有,未经授权,谢绝一切形式的转载