本文详解 ES2015 引入的 [[wp:a0]] 全局对象。涵盖其构造函数用法、size 属性及 set/get/delete/clear 等核心实例方法。通过对比 Object,分析 Map 在键值类型、遍历便捷性及哈希表性能上的优势,并提供 forEach 与 for...of 遍历示例。
Map为ES2015标准引入的全局对象,
Map实例存储键值对,且任意对象(含原始值)均可作为键或值。
1. 构造函数
Map必须作为构造函数调用,
new Map([iterable])
其参数可选,若提供则须为可迭代对象。
iterable的迭代结果即为,[key1, value1], [key2, value2], ...。
例如
// 1. 数组是一个iterable对象
m = new Map([[1, 'a'], [2, 'b']]); // Map(2) {1 => "a", 2 => "b"}
// 2. generator会返回一个iterable对象
gen = function*(){
yield [1, 'a'];
yield [2, 'b'];
}
iter = gen();
m = new Map(iter); // Map(2) {1 => "a", 2 => "b"}
2. 实例属性
m.size用于获取键的数量,
m = new Map([[1, 'a'], [2, 'b']]); // Map(2) {1 => "a", 2 => "b"}
m.size // 2
3. 实例方法
(1)m.has(key),用于判断键是否存在
(2)m.get(key),用于取值,若键不存在则返回undefined(3)m.set(key, value),用于设值,返回m(4)m.delete(key),若键存在且已被删除则返回true,若键不存在则返回false。
(5)m.clear(),用于删除所有键值对
(6)m.keys(),返回一个iterable对象,包含按插入顺序迭代的所有键
m = new Map([[1, 'a'], [2, 'b']]); // Map(2) {1 => "a", 2 => "b"}
[...m.keys()] // [1, 2]
(7)m.values(),返回一个iterable对象,包含按插入顺序迭代的所有值
m = new Map([[1, 'a'], [2, 'b']]); // Map(2) {1 => "a", 2 => "b"}
[...m.values()] // ["a", "b"]
(8)m.entries(),返回一个iterable对象,每个元素为[key, value],遍历顺序遵循键的插入顺序
m = new Map([[1, 'a'], [2, 'b']]); // Map(2) {1 => "a", 2 => "b"}
[...m.entries()] // [[1, "a"], [2, "b"]]
注:获取二维数组更便捷的方法是使用Array.from,它可直接接受Map作为参数,
m = new Map([[1, 'a'], [2, 'b']]); // Map(2) {1 => "a", 2 => "b"}
Array.from(m) // [[1, "a"], [2, "b"]]
Array.from亦可接受iterable对象,
Array.from(m.keys()) // [1, 2]
Array.from(m.values()) // ["a", "b"]
Array.from(m.entries()) // [[1, "a"], [2, "b"]]
(9)m.forEach(fn[, thisArg]),用于对Map以键的插入顺序进行遍历
m = new Map([[1, 'a'], [2, 'b']]); // Map(2) {1 => "a", 2 => "b"}
m.forEach((value, key)=>{
value // "a", "b"
key // 1, 2
});
注:第一个参数为值,第二个参数才是键。
除使用m.forEach外,Map还可使用for ... of进行遍历,
m = new Map([[1, 'a'], [2, 'b']]);
for(i of m){
i // [1, 'a'], [2, 'b']
}
4. 键的相等性判断
Map键的相等性判断采用“SameValueZero”算法:
(1)判断键相等时,NaN与NaN被视为相等。(即使NaN !== NaN)
(2)其他类型的键,依据===运算符进行判断。
(3)目前+0与-0被视为相等符合ES2015规范,但存在浏览器兼容性问题。
5. Map与Object对比
(1)Object的键仅限字符串(String)或符号(Symbol),
而Map的键可为任意值,包括函数、对象(object)或任何原始值(primitive value)。
(2)对于Map而言,可通过size属性直接获取键的数量,
而Object则需借助Object.keys(xxx).length间接获取自身属性的数量。
(3)Map实例为iterable对象,可直接用于遍历,
而Object需先获取其键,再使用键进行遍历。
(4)Object可拥有原型对象,自身属性可能无意间与原型属性冲突。
(尽管ES2015中可通过Object.create(null)创建无原型对象。)
(5)Map的键添加删除操作更为高效。
更多关于js中的Map函数使用方法请查看下面的相关链接