js数据类型
| 基本数据类型 | String,Number,Boolean,Null,undefined |
|---|---|
| 引用类型 | Object(Array、Function、Array、Date、RegExp) |
| —基本数据类型存在于栈区,例如var a=1; | |
![]() | |
| 在拷贝时,例如 var b=a; 栈中会重新为b开辟一个内存,如图 | |
![]() | |
| 所以当a改变时,并不影响b的值;因此基本数据类型并不存在深拷贝和浅拷贝的问题; |
—引用类型存在于堆中,例如var obj1 = [0,1,2,3]; 栈区中存储变量名及堆地址,堆地址指向堆中的数据;如图:

当进行拷贝时,例如var obj2 = obj1; obj2拷贝的是obj1存放数据的堆地址,所以当obj1中的数据改变时,obj2拷贝的堆地址并没有发生变化,obj2的数据也会随着obj1数据的变化而变化。

上述举例说明,浅拷贝与深拷贝只针对于引用类型数据;
先做简单的深拷贝与浅拷贝的描述,后续会继续做深化描述:设置变量A,B,为A赋值,再将A(源对象)赋给B(拷贝对象),当源对象数据改变时,拷贝对象数据也随之改变,称为浅拷贝,当源对象数据改变,而拷贝对象数据不随之改变时,称为深拷贝。
浅拷贝实现方法
1.直接赋值
let obj1={
id:2179,
info:{
name:"活着",
price:79,
author:"余华"
}
}
let obj2 = obj1;
obj1.id = 1928;
console.log(obj1.id,obj2.id); //1928 1928
2.Object.assign
let obj1={
id:2179,
info:{
name:"活着",
price:79,
author:"余华"
}
}
let obj2 = Object.assign({},obj1);
obj1.id = 1928;
obj1.info.price = 97;
console.log(obj1,obj2);

只深拷贝了第一层,内层直接引用,属于浅操作,扩展运算符同理,不再举例叙述
深拷贝实现方法
1.jQuery—extend(true, …) 第一个参数必须设置为true,才能实现深拷贝,默认为false
let obj1={
id:2179,
info:{
name:"活着",
price:79,
author:"余华"
}
}
let obj2 = $.extend(true,{},obj1);
obj1.id = 1928;
obj1.info.price = 101;
console.log(obj1,obj2);

内外层均实现了深拷贝
2.JSON.parse(JSON.stringify(…))
原理:将对象字符串化再转化为JSON对象,产生了新的对象
let obj1={
id:2179,
info:{
name:"活着",
price:79,
author:"余华"
}
}
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.id = 1928;
obj1.info.price = 101;
console.log(obj1,obj2);

3.递归拷贝
function deepCopy(obj){
var obj2 = Array.isArray(obj)?[]:{};
if(obj && typeof obj == "object"){
for(var i in obj){
if(obj.hasOwnProperty(i)){
if(i && typeof obj[i] == "object"){
obj2[i] = deepCopy(obj[i]);
}else{
obj2[i] = obj[i];
}
}
}
}
return obj2;
}
let obj1 = {
a:1,
b:2,
c:{
c1:"c-1",
c2:"c-2",
c3:{
c31:"c3-1",
c32:"c3-2"
}
}
};
let obj2 = deepCopy(obj1);
obj1.a = "1-modify";
obj1.c.c1 = "c-1-modify";
obj1.c.c3.c31 = "c3-1-modify";
console.log(obj1, obj2);

总结
浅拷贝:拷贝对象只是拷贝了源对象的第一层,内层直接引用源对象数据;
深拷贝:拷贝对象对源对象从外到内每一级别都进行了拷贝。
***************2023/01/30补充
js内置深拷贝方法:structuredClone
各种深拷贝方法对比参考:https://www.builder.io/blog/structured-clone



被折叠的 条评论
为什么被折叠?



