红宝书中weakmap一节提及函数私有的操作,使用了闭包和weakmap实现。
let wm = new WeakMap();
class User {
constructor(id) {
this.idProperty = Symbol("id");
this.setID(id);
}
setID(value) {
let that = wm.get(this) || {}; // {}为初始化
that[this.idProperty] = value;
wm.set(this, that);
}
getID() {
return wm.get(this)[this.idProperty];
}
}
let user = new User(123);
console.log(user.getID());
user.setID(456);
console.log(user.getID());
通过weakmap,将本对象与本对象属性进行绑定。但并非完全不可访问,通过 wm.get(user)[user.idProperty] 可以获得【即知道wm和user对象就可以直接访问】
下面的方式是通过闭包,让外界无法访问到weakmap。
const User = (() => {
let wm = new WeakMap();
class User {
constructor(id) {
this.idProperty = Symbol("id");
this.setID(id);
}
setID(value) {
let that = wm.get(this) || {}; // {}为初始化
that[this.idProperty] = value;
wm.set(this, that);
}
getID() {
return wm.get(this)[this.idProperty];
}
}
return User; // 封装类,返回类
})();
红皮书4.3.4讲到了内存管理/内存泄漏部分。
对于意外的全局变量,很好处理,做到编程时规范即可,也可以使用严格模式。
对于dom节点可能产生的内存泄露可以使用weakmap解决。
1. create产生的node,在移除node后的内存泄露
2. 引用node产生的内存泄露,移除node后的内存泄露
let wm = new WeakMap();
let p = document.createElement("p");
p.id = "p";
p.innerText = "memory leak";
document.querySelector("body").append(p);
wm.set(p, { innerText: 'memory leak' });
let q = document.querySelector("#p");
p = null; // 存在weakmap中
q = null; // 存在weakmap中
console.log(wm.get(document.querySelector("#p")).innerText) ;
console.log(wm.get(document.querySelector("#p")) === undefined);
document.querySelector("body").removeChild(document.querySelector("#p"));
console.log(wm.get(document.querySelector("#p")) === undefined);
// remove节点,weakmap中的键值一并被清除