1⃣️ 浅拷贝
直接赋值
let obj1 = {
name: 'kiw',
age: 18,
}
let obj2 = obj1;
console.log(obj1); //{name: "kiw", age: 18}
obj1.age = 22;
console.log(obj2); //{name: "kiw", age: 22}
Object.assign
let obj1 = {
a: 1,
b: {
c: 1
}
}
let obj2 = {
b: {
d: 2,
},
e: 4
}
Object.assign(obj2, obj1);
console.log(obj2);// {a: 1 b: {c: 1} e: 4}
2⃣️ 深拷贝
JSON.stringify & JSON.parse 实现深拷贝
let obj1 = {
name: 'kiw',
age: 18,
}
let str = JSON.stringify(obj1);
let str2 = str;
let obj2 = JSON.parse(str2)
console.log('obj2', obj2) // {name: "kiw", age: 18}
obj1.age = 22;
console.log('obj1', obj1) // {name: "kiw", age: 22}
console.log('obj2', obj2) // {name: "kiw", age: 18}
缺点:
1.如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式
2.如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象
3.如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失
4.如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5.?JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
const test = {
name: 'a',
date: liai,
};
// debugger
const copyed = JSON.parse(JSON.stringify(test));
test.name = 'test'
console.log('ddd', test, copyed)
6.?如果对象中存在循环引用的情况也无法正确实现深拷贝
使用递归实现深拷贝
let checkType = data => {
return Object.prototype.toString.call(data).slice(8, -1);
}
checkType([])
let deepClone = target => {
let targetType = checkType(target);
let result;
if (targetType === 'Object') {
result = {}
} else if (targetType === 'Array') {
result = []
} else {
return target
}
for (key in target) {
let value = target[key];
let valueType = checkType(value);
if (valueType === 'Object' || valueType === 'Array') {
result[key] = deepClone(value)
} else {
result[key] = value
}
}
return result
}
let arr1 = [1, 2, { age: 18 }];
let arr2 = deepClone(arr1);
arr2[2].age = 22;
console.log('arr2', arr2)
console.log('arr1', arr1)
网友评论