浅拷贝: 对了复杂数据类型,浅拷贝只是把引用地址赋值给了新的对象,改变这个新对象的值,原对象的值也会一起改变。
深拷贝: 对于复杂数据类型,拷贝后地址引用都是新的,改变拷贝后新对象的值,不会影响原对象的值。
所以关键点就在于对复杂数据类型的处理,这里写了两种写法,第二中比第一种有部分性能提升
const isObj = (val) => typeof val === "object" && val !== null;
// 写法1
function deepClone(obj) {
// 通过 instanceof 去判断你要拷贝的变量它是否是数组(如果不是数组则对象)。
// 1. 准备你想返回的变量(新地址)。
const newObj = obj instanceof Array ? [] : {}; // 核心代码。
// 2. 做拷贝;简单数据类型只需要赋值,如果遇到复杂数据类型就再次进入进行深拷贝,直到所找到的数据为简单数据类型为止。
for (const key in obj) {
const item = obj[key];
newObj[key] = isObj(item) ? deepClone(item) : item;
}
// 3. 返回拷贝的变量。
return newObj;
}
// 写法2 利用es6新特性 WeakMap弱引用 性能更好 并且支持 Symbol
function deepClone2(obj, wMap = new WeakMap()) {
if (isObj(obj)) {
// 判断是对象还是数组
let target = Array.isArray(obj) ? [] : {};
// 如果存在这个就直接返回
if (wMap.has(obj)) {
return wMap.get(obj);
}
wMap.set(obj, target);
// 遍历对象
Reflect.ownKeys(obj).forEach((item) => {
// 拿到数据后判断是复杂数据还是简单数据 如果是复杂数据类型就继续递归调用
target[item] = isObj(obj[item]) ? deepClone2(obj[item], wMap) : obj[item];
});
return target;
} else {
return obj;
}
}
这道题主要是的方案就是,递归加数据类型的判断。
如是复杂数据类型,就递归的再次调用你这个拷贝方法 直到是简单数据类型后可以进行直接赋值
作者:Ali2333
链接:https://juejin.cn/post/7079681931662589960
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
网友评论