var obj = {
name: 'Lance',
age: 28,
say() {
console.log('Hello');
},
a: {
b: {
c: 233
}
}
}
function deepClone(obj) {
// 处理 null 或者 undefined
if (obj === null || typeof obj !== 'object') {
return obj;
}
// 处理数组
if (Array.isArray(obj)) {
var arrCopy = [];
for (var i = 0; i < obj.length; i++) {
arrCopy[i] = deepClone(obj[i]);
}
return arrCopy;
}
// 处理普通对象
var objCopy = {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
objCopy[key] = deepClone(obj[key]);
}
}
return objCopy;
}
Map 键名 -> 任意类型 {}、[]都行
{} 键名 -> 字符串
WeakMap 键名 -> 只能是对象
const oBtn1 = document.querySelector('#btn1');
const oBtn2 = document.querySelector('#btn2');
oBtn1.addEventListener('click', handleBtn1Click, false);
oBtn2.addEventListener('click', handleBtn2Click, false);
function handleBtn1Click() {}
function handleBtn2Click() {}
// 某些场景下需要删除btn
oBtn1.remove();
oBtn2.remove();
// 而此刻 handleBtn1Click 不会被销毁,理论上需要手动销毁
handleBtn1Click = null;
handleBtn2Click = null;
有了 WeakMap 就可以这样做:
const oBtnMap = new WeakMap();
oBtnMap.set(oBtn1, handleBtn1Click);
oBtnMap.set(oBtn2, handleBtn2Click);
oBtn1.addEventListener('click', oBtnMap.get(oBtn1), false);
oBtn2.addEventListener('click', oBtnMap.get(oBtn2), false);
oBtn1.remove();
oBtn2.remove();
WeakMap 是弱引用,一旦 oBtn1 被 remove 掉,它就会被回收。所以这也解释了为什么 WeakMap 的键名要是个对象类型。
oBtn1 都被回收了,相应的键值 handleBtn1Click 也会被回收
WeakMap 中键名的对象,在外界没有被引用了,就会被回收,同时一并的把相应的键值也给回收了。
undefined == null
true