Map
对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。
一个Map对象在迭代时会根据对象中元素的插入顺序来进行 — 一个 for...of
循环在每次迭代后会返回一个形式为[key,value]的数组。
- 键的比较是基于
sameValueZero
算法: NaN
是与NaN
相等的(虽然NaN !== NaN
),剩下所有其它的值是根据===
运算符的结果判断是否相等。- 在目前的ECMAScript规范中,
-0
和+0
被认为是相等的,尽管这在早期的草案中并不是这样。有关详细信息,请参阅浏览器兼容性 表中的“Value equality for -0 and 0”。
Map与普通对象的区别:
Map | Object | |
---|---|---|
意外的键 |
|
一个 注意: 虽然 ES5 开始可以用 |
键的类型 | 一个 Map 的键可以是任意值,包括函数、对象或任意基本类型。 |
一个Object 的键必须是一个 String 或是Symbol 。 |
键的顺序 |
|
一个 注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。 |
Size | const map = new Map(); |
先转换为数组,然后获取数组长度, |
迭代 |
|
迭代一个 必须将它们转换为数组,如使用 |
性能 | 在频繁增删键值对的场景下表现更好。 |
在频繁添加和删除键值对的场景下未作出优化。 |
let myMap = new Map();
myMap.set(NaN, "not a number");
myMap.get(NaN); // "not a number"
let otherNaN = Number("foo");
myMap.get(otherNaN); // "not a number" 虽然NaN!==NaN
遍历:
let myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (let [key, value] of myMap) {
console.log(key + " = " + value);
}
// 将会显示两个log。一个是"0 = zero"另一个是"1 = one"
for (let key of myMap.keys()) {
console.log(key);
}
// 将会显示两个log。 一个是 "0" 另一个是 "1"
for (let value of myMap.values()) {
console.log(value);
}
// 将会显示两个log。 一个是 "zero" 另一个是 "one"
for (let [key, value] of myMap.entries()) {
console.log(key + " = " + value);
}
// 将会显示两个log。 一个是 "0 = zero" 另一个是 "1 = one"
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的解构语法:
const map = new Map([['one', 1], ['two', 2]]);
const arr = [...map];
map对象和常规对象互换:
const mapToObj = map => {
const obj = {};
map.forEach((key, value) => { obj[key] = value });
return obj;
};
const objToMap = obj => {
const map = new Map();
Object.keys(obj).forEach(key => { map.set(key, obj[key]) });
return map;
};
ES2019的首次展示中,我们看见了Object
引入了2个新方法:Object.entries()
和Object.fromEntries()
,这可以使上述方法简化许多:
const obj2 = Object.fromEntries(map);
const map2 = new Map(Object.entries(obj));
其他:
请注意!为Map设置对象属性也是可以的,但是可能引起大量的混乱。
所以,你还是可以这样做...
let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'
console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
...但是,这样做的话,它的行为会不符合预期:
wrongMap.has('bla') // false
wrongMap.delete('bla') // false
console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
无论如何,和正确用法比较起来,几乎没有什么不同:
let myMap = new Map()
myMap.set('bla','blaa')
myMap.set('bla2','blaa2')
console.log(myMap) // Map { 'bla' => 'blaa', 'bla2' => 'blaa2' }
myMap.has('bla') // true
myMap.delete('bla') // true
console.log(myMap) // Map { 'bla2' => 'blaa2' }
来源:oschina
链接:https://my.oschina.net/u/560237/blog/4881756