本文参考:《ECMAScript 6入门》阮一峰
Map
一. Map出现的意义
- Object提供了一种(字符串 - 值)的hash结构,但是键(key)只能是字符串。
- Map相当于加强版的对象,键(key)的取值可以是所有类型的值。所以,Map比起Object更适合于作为哈希表。
二. 创建Map
- 使用构造函数创建Map
let map = new Map();
- 构造函数中传入数组类型参数可以添加键值对的成员。
let map = new Map([
['key1','value1'],
['key2','value2']
]);
console.log(map);
// Map { 'key1' => 'value1', 'key2' => 'value2' }
三. Map的成员
1. 对同一个键多次赋值,后面的值将覆盖前面的值。
let map = new Map([
['key1','value1'],
['key1','value2']
]);
console.log(map);
// Map { 'key1' => 'value2' }
2. 怎么才是相等的键(同一个键)?
- 数字、字符串、布尔值情况下,判断值是否严格相等(===)。
let map1 = new Map([
[-0,'value1'],
[+0,'value2']
]);
console.log(map1);// Map { 0 => 'value2' }
let map2 = new Map([
['1','value1'],
['1','value2']
]);
console.log(map2);// Map { '1' => 'value2' }
let map3 = new Map([
[true,'value1'],
[true,'value2']
]);
console.log(map3);// Map { true => 'value2' }
- 两个键都是NaN也被判断为相同成员。
let map4 = new Map([
[NaN,'value1'],
[NaN,'value2']
]);
console.log(map4);// Map { NaN => 'value2' }
- 引用类型需要判断内存地址相等。Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。
let key1 = [1,2];
let key2 = [1,2];
let objMap = new Map([
[key1,'value1'],
[key2,'value2']
]);
console.log(objMap);
// Map { [ 1, 2 ] => 'value1', [ 1, 2 ] => 'value2' }
四. Map的属性和方法
- 属性Map.size,返回成员数量(类比数组的length)
let map = new Map([
[0,1],
[1,2],
[2,3],
[3,4]
]);
console.log(map.size);// 4
- 操作方法
方法名 | 描述 |
---|---|
set(key, value) | 设置成员,返回的是Map本身 |
get(key) | 读取key对应的键值,如果找不到key,返回undefined |
has(key) | 根据key判断是否存在某个成员,返回一个布尔值 |
delete(key) | 删除成员,返回布尔值 |
clear() | 清空Map |
- 遍历方法(Map内置了Iterator接口),遍历方法与Set一样
方法名 | 描述 |
---|---|
keys() | 返回键名的遍历器 |
values() | 返回键值的遍历器 |
entries() | 返回所有成员的遍历器 |
forEach() | 遍历Map的所有成员 |
- 值得一提的是使用entries()配合解构赋值以及
for of
(其实entries方法就是内置的Symbol.iterator属性)
let map = new Map([
[0,1],
[1,2],
[2,3],
[3,4]
]);
for(let [key,value] of map.entries()){
console.log(key,value);
}
// 0 1
// 1 2
// 2 3
// 3 4
// 等价于
for(let [key,value] of map){
console.log(key,value);
}
五. Map转换为数组
- 1. Array.from()
let map = new Map([
[0,1],
[1,2],
[2,3],
[3,4]
]);
console.log(Array.from(map));// [ [ 0, 1 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ] ]
- 2. 扩展运算符
let map = new Map([
[0,1],
[1,2],
[2,3],
[3,4]
]);
console.log([...map]);// [ [ 0, 1 ], [ 1, 2 ], [ 2, 3 ], [ 3, 4 ] ]
WeakMap
一. 与Map的区别
1. 键名只能是对象(但不允许null)
2. 键名是对象的弱引用(不计入垃圾回收机制)。假如对象被回收,WeakMap成员中对应的键也被移除。
- 垃圾回收机制中有一种策略就是使用引用计数,WeakMap将对象作为键名时不会使该对象的引用加1。这样的好处是有助于防止内存泄漏。(因为假如对象存在被引用时不会被回收)
3. 因为上面的特点2的原因,导致WeakMap没有遍历操作(keys、values、entries),没有size属性,也不支持clear。
二. WeakMap仅有的方法
方法名 | 描述 |
---|---|
set(key, value) | 设置成员,返回的是WeakMap本身 |
get(key) | 读取key对应的键值,如果找不到key,返回undefined |
has(key) | 根据key判断是否存在某个成员,返回一个布尔值 |
delete(key) | 删除成员,返回布尔值 |
三. WeakMap的应用(详情见《ECMAScript 6入门》)
- DOM节点作为键名
- 部署私有属性
网友评论