深拷贝:拷贝值;浅拷贝: 拷贝地址
深拷贝的方法
JSON 对象:
JSON.parse(JSON.stringify(a)) // a 只能是扁平对象
//不能拷贝 function,会直接丢弃
//如果只有一级属性,则就是深拷贝
//如果一级属性里面有引用数据类型,则这个只是浅拷贝了
参数:target--->目标对象
source--->源对象
返回值:target,即目标对象
Object.assign(target,source):
Object.assign({},a)
/* for in 递归拷贝会将 原型上的属性方法全部拷贝过来 */
for in 递归拷贝:
function clone(source) {
let target = source instanceof Array ? [] : {}
for (let key in source) {
if (typeof source[key] === 'object') {
target[key] = clone(source[key])
} else {
target[key] = source[key]
}
}
return target
}
/**
* 深拷贝
* @param {Object} obj 目标对象
* @param {WeakMap} hash处理循环引用
* (一个对象第一次被复制会被weakMap存起来,二次复制使用的时候直接取出来,加快速度)
* @returns {Object} 深拷贝后的对象
*/
export function deepClone(obj, hash = new WeakMap()) {
if (!obj || typeof obj !== 'object') {
return obj;
}
// 如果是日期或正则对象,直接返回新的对象
if (obj instanceof Date) {
return new Date(obj);
}
if (obj instanceof RegExp) {
return obj;
}
// 如果对象已经在hash中,说明存在循环引用,直接返回hash中的值
if (hash.has(obj)) {
return hash.get(obj);
}
const result = Array.isArray(obj) ? [] : {};
Object.keys(obj).forEach((key) => {
if (obj[key] && typeof obj[key] === 'object') {
result[key] = deepClone(obj[key],hash);
} else {
result[key] = obj[key];
}
});
hash.set(obj, result); // 创建新对象,并加入hash中
return result;
}
`
关于weakMap
`
// 创建一个新的 WeakMap
let weakmap = new WeakMap();
// 创建一个对象
let obj = { name: "Example" };
// 将对象作为键,值可以是任何类型
weakmap.set(obj, "This is an example value");
// 获取与对象关联的值
console.log(weakmap.get(obj)); // 输出: "This is an example value"
// 检查一个键是否在 WeakMap 中
console.log(weakmap.has(obj)); // 输出: true
// 遍历 WeakMap 中的所有键值对
weakmap.forEach((value, key) => {
console.log(`Key: ${key}, Value: ${value}`);
});
// 删除键值对
weakmap.delete(obj);
// 再次尝试获取值,将返回 undefined,因为键已经被删除
console.log(weakmap.get(obj)); // 输出: undefined
// 检查键是否还在 WeakMap 中
console.log(weakmap.has(obj)); // 输出: false
// 尝试遍历空的 WeakMap
weakmap.forEach((value, key) => {
console.log(`Key: ${key}, Value: ${value}`);
}); // 不会有任何输出
// 清理对象,使其不再被引用
obj = null;
// 由于 obj 不再被引用,并且它曾是 WeakMap 的键,因此对应的键值对会自动从 WeakMap 中删除
// 在这种情况下,由于 obj 已经被显式地设置为 null,所以相关的键值对已经自动被清除