Map 是一个含有数据的键的集合,跟普通的 Object一样。但是它们最大的差别是Map允许键是任何类型。 关于Map的方法和属性如下:
new Map() 创建一个空集合 map.set(key, value) 存储含有值的键 map.get(key) 根据键来返回值,如果 key 不在 map 里将会返回 undefined map.has(key) 如果key存在则返回 true,否则返回 false map.delete(key) 根据键来删除值 map.clear 清空集合 map.size 返回当前全部元素的数量 举个例子:
let map = new Map(); map.set('1', 'str1'); map.set(1, 'num1'); map.set(true, 'bool1'); //Map 会保持类型,而不会像Object将键转化为字符串 alert( map.get(1) ); // 'num1' alert( map.get('1') ); // 'str1'Map 还可以使用对象作为键 示例:
let john = { name: 'John' }; //创建一个集合可以存储每个游客的来访次数 let visitsCountMap = new Map(); // john 的来访次数是123 visitsCountMap.set(john, 123); //读取 john 的来访次数 alert( visitsCountMap.get(john) ); // 123使用对象作为键是 Map 最出名也是最重要的特点。
Map 是怎么比较键的? 为了测试键的一致性,Map 使用 SameValueZero 算法。它大致上使用严格相等 ===,但不同的是 NaN 被看成是等于 NaN。所以 NaN 也可以被用作键。(这个算法不能被改变或者自定义)
链式调用 每一次调用 map.set 都会返回集合本身,所以我们可以使用:
map.set('1', 'str1').set(1, 'num1').set(true, 'bool1');如果要在 map 里使用循环,可以使用以下三个方法:
map.keys() 返回所有键的迭代器 map.values() 返回所有值的迭代器 map.entries() 返回包含所有键值对的迭代器,在 for…of 循环中默认被使用 示例:
let recipeMap = new Map([ ['cucumber', 500], ['tomatoes', 350], ['onion', 50] ]); //迭代键 for (let vegetable of recipeMap.keys()) { alert(vegetable); // cucumber, tomatoes, onion } //迭代值 for (let amount of recipeMap.values()) { alert(amount); // 500, 350, 50 } //迭代键值对 for (let entry of recipeMap) { // 效果跟 recipeMap.entries() 相同 alert(entry); // 依次是 cucumber,500 tomatoes,350 onion,50 }按顺序插入 迭代的顺序与插入键的顺序相同。Map 会保持相同的顺序,不像普通 Object 不保证顺序。 除此之外,Map 有个内建 forEach 方法,跟 Array 一样:
//对每个 (key, value) 对运行 forEach 函数 recipeMap.forEach( (value, key, map) => { alert(`${key}: ${value}`); // cucumber: 500 })Object.entries: 把对象转化为 map 当 Map 被创建之后,我们可以传入带有键值对的数组(或其它可迭代的对象)来进行初始化,像这样:
//包含 [key, value] 对的数组 let map = new Map([ ['1', 'str1'], [1, 'num1'], [true, 'bool1'] ]); alert( map.get('1') );如果我们有个纯对象,并且想利用这个纯对象来创建 Map,可以使用内建方法 Object.entries(obj),它返回一个具有相同格式的并且带有键值对的数组对象。 示例:
let obj = { name: 'John', age: 30 }; let map = new Map(Object.entries(obj)); alert( map.get('name') ); // John这里,Object.entries 返回一个含有键值对的数组:[ [‘name’,‘John’], [‘age’, 30] ]。这就是 Map 所需要的参数格式。
Object.fromEntries: 把 map 转化为对象 我们刚刚已经利用 Object.entries(obj) 把一个纯对象转化成 Map Object.fromEntries 方法的作用是相反的:给定一个具有 [key, value] 对的数组,它会根据给定数组转化为 Object:
let prices = Object.fromEntries([ ['banana', 1], ['orange', 2], ['meat', 3] ]); alert(prices.orange); // 2我们可以使用 Object.fromEntries 从 Map 中得到一个纯对象。 例如:我们存了数据在 Map 中,但是我们需要把它转给需要纯对象的第三方代码。 示例:
let map = new Map(); map.set('banana', 1); map.set('orange', 2); map.set('meat', 3); let obj = Object.fromEntries(map.entries()); alert(obj.orange); // 2调用 map.entries() 将返回含有键值对的数组,这刚好是 Object.fromEntries 所需要的格式。 当然,使用下面的方式也是可以的:
let obj = Object.fromEntries(map);上面的代码作用是一样的,因为 Object.fromEntries 需要一个可迭代对象作为参数,map 的标准迭代会返回跟 map.entries() 一样的键值对。