Map概述
- JS中的对象,本质上是键值对的集合,只能用字符串或Symbol当作键名。
Map数据结构类似对象,也是键值对的集合,区别是键名不限于字符串,可以使用各种类型的值做当键名。
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o)
Map也可以接受一个数组(或者具有Iterator接口的其他数据结构)作为参数,该数组的成员是一个个键值对的数组。
const map = new Map([
['name', '张三'],
['title', 'Author']
]);
map.size
map.has('name')
map.get('name')
map.has('title')
map.get('title')
- 只有对同一个对象的引用,
Map才将其视为同一个键。
const map = new Map();
map.set(['a'], 1);
map.get(['a'])
- 如果键名是一个原始值,则只要两个值
严格相等就会被视为同一个键。
let map = new Map();
map.set(-0, 123);
map.get(+0)
map.set(true, 1);
map.set('true', 2);
map.get(true)
map.set(undefined, 3);
map.set(null, 4);
map.get(undefined)
map.set(NaN, 123);
map.get(NaN)
实例属性
size
const map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size
实例操作方法
set()
- 设置键名以及对应的键值,然后返回整个Map。如果对应的
key已经有值,则该键值会被更新。
- 因为
set()会返回Map,因此可以采用链式写法。
let map = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');
get()
- 读取
key对应的键值,如果找不到返回undefined。
const m = new Map();
const hello = function() {
console.log('hello');
};
m.set(hello, 'Hello ES6!')
m.get(hello)
has()
- 返回一个布尔值,表示某个键是否在当前
Map对象中。
const m = new Map();
m.set('edition', 6);
m.has('edition')
m.has('years')
delete()
- 删除某个
key,返回布尔值,如果删除失败返回false。
const m = new Map();
m.set(undefined, 'nah');
m.delete(undefined)
clear()
let map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size
map.clear()
map.size
实例遍历方法
Map的遍历顺序就是插入顺序。keys()、values()、entries()返回的都是遍历器对象(Iterator)。
keys()
values()
entries()
const map = new Map([
['F', 'no'],
['T', 'yes'],
]);
for (let key of map.keys()) {
console.log(key);
}
for (let value of map.values()) {
console.log(value);
}
for (let item of map.entries()) {
console.log(item[0], item[1]);
}
for (let [key, value] of map.entries()) {
console.log(key, value);
}
for (let [key, value] of map) {
console.log(key, value);
}
forEach()
- 使用回调函数遍历每个成员。需要注意的是参数一是
键值;参数二是键名。
const map = new Map()
.set('a', 1)
.set('b', 2)
.set('c', 3);
map.forEach((value, key) => {
console.log(key, value)
})
与其他数据结构的转换
Map 转为数组
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);
[...myMap]
数组转为 Map
new Map([
[true, 7],
[{foo: 3}, ['abc']]
])
Map 转为对象
- 如果
Map的键都是字符串,那么可以无损转为对象。如果有非字符串的键名,会先转为字符串。
let c = [1, 2, 3];
const map = new Map()
.set('a', 1)
.set('b', 2)
.set(c, 3);
function map2Obj(map) {
let obj = {};
for (const [key, value] of map) {
obj[key] = value;
}
return obj;
}
let o = map2Obj(map);
o
对象转为 Map
let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));
WeakMap概述
- 与
Map结构类似,也是键值对的集合。与Map的区别一是WeakMap的键名只能是对象和Symbol;区别二是WeakMap的键名所引用的对象都是弱引用,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。
- 没有遍历操作(即没有
keys()、values()和entries()方法),也没有size属性。
new WeakMap()
.set({a: 1}, 1)
.set({b: 2}, 2);
实例操作方法
get()
- 读取
key对应的键值,如果找不到返回undefined。
set()
- 设置键名以及对应的键值,然后返回整个WeakMap。如果对应的
key已经有值,则该键值会被更新。
- 因为
set()会返回WeakMap,因此可以采用链式写法。
has()
- 返回一个布尔值,表示某个键是否在当前
Map对象中。
delete()
- 删除某个
key,返回布尔值,如果删除失败返回false。