前言
在ES6中引入JavaScript的新特性中,我们看到了Set和Map的介绍。与常规对象和Array不同的是,它们是“键控集合(keyed collections)”。这就是说它们的行为有稍许不同,并且在特定的上下文中使用,它们可以提供相当大的性能优势。
在这篇文章中,我将剖析Map,它究竟有何不同,哪里可以派上用场,相比于常规对象有什么性能优势。
Map与常规对象有什么不同
Map和常规对象主要有2个不同之处。
1.无限制的键(Key)
常规JavaScript对象的键必须是String或Symbol,下面的对象说明的这一点:
const symbol = Symbol();const string2 = 'string2';const regularObject = { string1: 'value1', [string2]: 'value2', [symbol]: 'value3'};
相比之下,Map允许你使用函数、对象和其它简单的类型(包括NaN)作为键,如下代码:
const func = () => null;const object = {};const array = [];const bool = false;const map = new Map();map.set(func, 'value1');map.set(object, 'value2');map.set(array, 'value3');map.set(bool, 'value4');map.set(NaN, 'value5');
在链接不同数据类型时,这个特性提供了极大的灵活性。
2.直接遍历
在常规对象中,为了遍历keys、values和entries,你必须将它们转换为数组,如使用Object.keys()、Object.values()和Object.entries(),或者使用for ... in循环,因为常规对象不能直接遍历,另外for ... in循环还有一些限制:它仅仅遍历可枚举属性、非Symbol属性,并且遍历的顺序是任意的。
而Map可以直接遍历,并且由于它是键控集合,遍历的顺序和插入键值的顺序是一致的。你可以使用for ... of循环或forEach方法来遍历Map的entries,如下代码:
for (let [key, value] of map) { console.log(key); console.log(value);};map.forEach((key, value) => { console.log(key); console.log(value);});
还有一个好处就是,你可以调用map.size属性来获取键值数量,而对于常规对象,为了做到这样你必须先转换为数组,然后获取数组长度,如:Object.keys({}).length。
Map和Set有何不同
Map的行为和Set非常相似,并且它们都包含一些相同的方法,包括:has、get、set、delete。它们两者都是键控集合,就是说你可以使用像forEach的方法来遍历元素,顺序是按照插入键值排列的。
最大的不同是Map通过键值(key/value)成对出现,就像你可以把一个数组转换为Set,你也可以把二维数组转换为Map:
const set = new Set([1, 2, 3, 4]);const map = new Map([['one', 1], ['two', 2], ['three', 3], ['four', 4]]);
类型转换
要将Map切换回数组,你可以使用ES6的结构语法:
新闻热点
疑难解答
图片精选