1. 为什么会出现 Map?
结论:弥补对象的 key 只能是字符串,不能是对象的缺陷。
例子如下:
// Object 的对象只能是字符串,所以下面的 kk 中的 k,y 实际上被转化成字符串。
const k = {name:1};
const y = "age"
const kk = {
k:'pang',
y:18
}
console.log(kk)
输出结果如下:
// 如果想用变量作为 key 需要用下面这种写法,用[] 包裹
const k = {name:1};
const y = "age"
const kk = {
[k]:'pang',
[y]:18
}
console.log(kk)
输出如下:
重点⚠️:
可以看到,因为 Object 的对象只能是 string 类型,所以会自动地把变量的内容通过 Object.prototype.toString.call(值) 转换成 字符串。所以如果变量是个引用类型,就是被转换成 [object Object] 。
所以下面这段代码:
// 如果有多个引用类型
const k = {name:1};
const z = {hobby:'coding'}
const y = "age"
const kk = {
[k]:'pang',
[z]:'dddd',
[y]:18
}
console.log(kk)
输出结果是:
2. Map
也具有不重复性,不过有些特殊,对于 -0,+0 和 NaN 的处理不太一样
// 认为 -0 等于 0 ; NaN 等于 NaN
const map = new Map();
map.set(0,'1');
map.set(-0,'2');
map.set(NaN,'3');
map.set(NaN,'4');
console.log(map)
方法如下: 
初始化Map:
应该是传入二维数组 [[],[]] 。
const map = new Map([["a",'1'],["b",2]]);
console.log(map)
赋值:
const map = new Map();
map.set(key,value)
一个容易被误导的问题:
const map = new Map();
map.set(['a'],1);
map.set(['a'],2);
console.log(map.get(['a']))
//结果是 undefined ,因为这三个引用类型都是独立的数据哦,别因为一样被误解,避免这种可以用变量
const a = ['a']
const map = new Map();
map.set(a,1);
map.set(a,2);
console.log(map.get(a)) // 2
3. WeakMap
弱集合中的键 只能是 Object 或者继承自 Object 的类型。
主要作用:弱引用(针对内存泄露的问题)和 私有成员
使用场景:
- 使资源被垃圾回收机制及时回收
例如有一个 add 按钮,控制 count = 0,点击 count + 1。当使用完的时候,要移除点击事件,但是如果不移除 count ,它就会一直存在,如果这个按钮控制更多数据,那就会有更多数据保存在内存中没有被释放。这个时候如果使用弱引用 WeakMap 保存,以按钮作为key ,控制的数据为值,当移除按钮的时候其值也会被回收,避免的占用内存的问题。
let wm = new WeakMap();
wm.set(button,{count:0})
- 私有成员
const User = (() => {
const wm = new WeakMap();
class User {
constructor(id) {
this.idProperty = Symbol('id');
this.setId(id);
}
setPrivate(property, value) {
const privateMembers = wm.get(this) || {};
privateMembers[property] = value;
wm.set(this, privateMembers);
}
getPrivate(property) {
return wm.get(this)[property];
}
setId(id) {
this.setPrivate(this.idProperty, id);
}
getId(id) {
return this.getPrivate(this.idProperty);
}
}
return User;
})();
const user = new User(123);
alert(user.getId()); // 123
user.setId(456);
alert(user.getId()); // 456