深浅拷贝都只针对于引用数据类型,浅拷贝只复制指向某个对象的指针,而不复制对象本身,修改副本会改动原对象,深拷贝不会。
浅拷贝
- Object.assign(只拷贝属性,改变副本的属性值并不会改变原对象的属性值,但是属性为引用类型时,会一起改变)
let obj = {
a: 1,
b: 2,
c: {
d: 3,
e: 4
}
};
let obj1 = Object.assign({},obj);
obj1.a = 3;
obj1.c.d = 100;
console.log(obj1.a,obj.a);
//3 1 原属性值未改变
console.log(obj1.c.d,obj.c.d);
//100 100 都发生了改变
- for in方法实现浅拷贝(与上同)
function simpleCopy(obj){
let obj1 = Array.isArray(obj)?[]:{};
for(let i in obj){
obj1[i] = obj[i];
}
return obj1;
}
let obj = {
a: 1,
b: 2,
c: {
d: 3,
e: 4
}
};
let obj1 = simpleCopy(obj);
obj1.a = 3;
obj1.c.d = 100;
console.log(obj1.a,obj.a);
//3 1 原属性值未改变
console.log(obj1.c.d,obj.c.d);
//100 100 都发生了改变
深拷贝
- 使用递归拷贝所有层级属性
function deepClone(obj){
let obj1 = Array.isArray(obj)?[]:{};
if(obj && typeof obj === "object"){
for(key in obj){
//排除继承来的属性
if(obj.hasOwnProperty(key)){
if(obj[key] && typeof obj[key]==="object"){
obj1[key] = deepClone(obj[key])
}else{
obj1[key] = obj[key];
}
}
}
}
return obj1;
}
let obj = {
a: 1,
b: 2,
c: {
d: 3,
e: 4
}
};
let obj1 = deepClone(obj);
obj1.a = 3;
obj1.c.d = 100;
console.log(obj1.a,obj.a);
//3 1 原属性值未改变
console.log(obj1.c.d,obj.c.d);
//100 3 原引用值也未发生改变,实现了深拷贝
function deepClone(obj){
if(obj === null || typeof obj !== 'object'){
return obj;
}
let clone = Array.isArray(obj)?[]:{};
for(let key in obj){
clone[key] = deepClone(obj[key]);
}
return clone;
}
或使用Object.keys(obj).map()来遍历key值
function deepClone(obj){
let obj1 = Array.isArray(obj)?[]:{};
if(obj && typeof obj === "object"){
Object.keys(obj).map((key)=>{
if(obj[key] && typeof obj[key]==="object"){
obj1[key] = deepClone(obj[key])
}else{
obj1[key] = obj[key];
}
})
}
return obj1;
}
let obj = {
a: 1,
b: 2,
c: {
d: 3,
e: 4
}
};
let obj1 = deepClone(obj);
obj1.a = 3;
obj1.c.d = 100;
console.log(obj1.a,obj.a);
//3 1 原属性值未改变
console.log(obj1.c.d,obj.c.d);
//100 3 原引用值也未发生改变,实现了深拷贝
- 使用JSON.stringify和JSON.parse实现深拷贝
function deepClone(obj){
let temp = JSON.stringify(obj);
let obj1 = JSON.parse(temp);
return obj1;
}
let obj1 = deepClone(obj);
obj1.a = 3;
obj1.c.d = 100;
console.log(obj1.a,obj.a);
//3 1 原属性值未改变
console.log(obj1.c.d,obj.c.d);
//100 3 原引用值也未发生改变,实现了深拷贝