通俗解释:深拷贝是内容拷贝,浅拷贝是地址拷贝
深拷贝
<script>
// 深拷贝,引用数据类型复制一份,复制后修改数据内容互不影响
const obj = {
id: 1,
name: "andy",
msg: {
age: 18
},
color: ["pink", "blue"]
}
const o = {};
// 封装克隆函数
function deepClone(newObj, oldObj) {
// 使用forin遍历,因为它可以遍历数组也可以遍历对象
for (let k in oldObj) { // 遍历旧对象取值,k是old的属性名,可以遍历数组和对象
//拿到旧数组的值,判断是否是复杂数据类型
let item = oldObj[k]; // 将复杂数据类型的值给item
if (Array.isArray(item)) {
// 先判断值是否是数组,如果是就递归循环这个数组并赋值
newObj[k] = []; // 将类型变成数组,是数组的话,k就是索引号
deepClone(newObj[k], item); // 将索引号给到数组,并将值赋值到相应的属性名下
} else if (item instanceof Object) {
// 判断是否是对象
newObj[k] = {};
deepClone(newObj[k], item);
} else {
// 是普通数据类型.直接赋值
newObj[k] = item;
}
}
}
deepClone(o, obj);
console.log(o);
</script>
浅拷贝
// 浅拷贝
const obj = {
id: 1,
name: "andy",
msg: {
age: 18
},
color: ["pink", "blue"]
}
console.log("obj", obj);
const o = {};
for (let k in obj) {
// k是obj的属性名 obj[k]是obj的属性值
o[k] = obj[k]; // 将k属性名作为o的属性名,obj属性值给到o
}
console.log("o", o);
// 浅拷贝语法糖
Object.assign(o, obj);
console.log("合并", o);
// 可以进行对象的合并
const obj1 = {
test: 11
};
// 如果拷贝的值得属性于之前的有相同,则值会覆盖
Object.assign(obj1, {
test: 1
})
console.log(obj1);
/**
* 深度拷贝
*/
export const deepClone = function (obj, hash = new WeakMap()) {
if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
// 可能是对象或者普通的值 如果是函数的话是不需要深拷贝
if (typeof obj !== "object") return obj;
// 是对象的话就要进行深拷贝
if (hash.get(obj)) return hash.get(obj);
let cloneObj = new obj.constructor();
// 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 实现一个递归拷贝
cloneObj[key] = deepClone(obj[key], hash);
}
}
return cloneObj;
}