当前位置:网站首页>通过 代码实例 理解 浅复制 与 深复制
通过 代码实例 理解 浅复制 与 深复制
2022-07-01 08:42:00 【ylnzzl】
目录
说明
如果一个对象的成员都是值类型,那么可以通过拓展运算符或者Object.assign来实现深复制。如果一个对象的成员的类型除了值类型外,还包含引用类型,那么可以通过JSON.parse(JSON.stringify(obj))或者递归遍历复制来实现深复制,其中JSON.parse(JSON.stringify(obj))这种方式会丢失值为undefined和function的属性,而且JSON.parse只能将Date对象解析为字符串而无法解析为原始的Date对象。
示例一
let obj1={a:1,b:"2",c:[1,2],d:{e:1,f:2}};
let obj2={...obj1};// 或者 let obj2={}; Object.assign(obj2,obj1);
obj2.b="3";
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "3", c: Array [1, 2], d: Object { e: 1, f: 2 } }
obj2={...obj1}; // 或者 obj2={}; Object.assign(obj2,obj1);
obj2.c=[2,3];
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [2, 3], d: Object { e: 1, f: 2 } }
obj2={...obj1}; // 或者 obj2={}; Object.assign(obj2,obj1);
obj2.c[0]=0;
console.log(obj1); // Object { a: 1, b: "2", c: Array [0, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [0, 2], d: Object { e: 1, f: 2 } }
obj1={a:1,b:"2",c:[1,2],d:{e:1,f:2}}; // 因为上面代码改变了obj1的值,所以这里重置一下。
obj2={...obj1}; // 或者 obj2={}; Object.assign(obj2,obj1);
obj2.d={e:3};
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 3 } }
obj2={...obj1}; // 或者 obj2={}; Object.assign(obj2,obj1);
obj2.d.e=4;
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 4, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 4, f: 2 } }示例二
let obj1={a:1,b:"2",c:[1,2],d:{e:1,f:2}};
let obj3={a:null,b:undefined,c:NaN,d:false,e:0,f:'',g:{e:1,f:2},h:new Date(),j:function(){return 1;}};
let obj2=JSON.parse(JSON.stringify(obj1));
obj2.b="3";
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "3", c: Array [1, 2], d: Object { e: 1, f: 2 } }
let obj4=JSON.parse(JSON.stringify(obj3)); // obj4中移除了值为undefined和function的属性,而且值为NaN的属性其值被转换为了null。此外对于值为Date对象的属性,并没有复制为Date对象。
obj4.g.e="3";
console.log(obj3); // Object { a: null, b: undefined, c: NaN, d: false, e: 0, f: "", g: Object { e: 1, f: 2 }, h: Mon Jun 13 2022 13:23:13 GMT+0800 (中国标准时间), j: function(){return 1;} }
console.log(obj4); // Object { a: null, c: null, d: false, e: 0, f: "", g: Object { e: "3", f: 2 }, h: "2022-06-14T11:39:11.716Z" }
obj2=JSON.parse(JSON.stringify(obj1));
obj2.c=[2,3];
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [2, 3], d: Object { e: 1, f: 2 } }
obj2=JSON.parse(JSON.stringify(obj1));
obj2.c[0]=0;
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [0, 2], d: Object { e: 1, f: 2 } }
obj2=JSON.parse(JSON.stringify(obj1));
obj2.d={e:3};
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 3 } }
obj2=JSON.parse(JSON.stringify(obj1));
obj2.d.e=4;
console.log(obj1); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 1, f: 2 } }
console.log(obj2); // Object { a: 1, b: "2", c: Array [1, 2], d: Object { e: 4, f: 2 } }示例三
let obj1={b:1,a:function(){return 1},};
let obj2=obj1; // 浅复制,改变复制后的对象时,会连带改变原对象。
obj2.a=function(){return 2};
console.log(obj1); // Object { b: 1, a: function(){return 2} }
console.log(obj2); // Object { b: 1, a: function(){return 2} }
obj2.b=2;
console.log(obj1); // Object { b: 2, a: function(){return 2} }
console.log(obj2); // Object { b: 2, a: function(){return 2} }
let obj3={b:1,a:function(){return 1},};
let obj4=obj3;
obj4={b:1,a:function(){return 2},}; // 给obj4重新赋值后,obj4就与obj3没关系了。
console.log(obj3); // Object { b: 1, a: function(){return 1} }
console.log(obj4); // Object { b: 1, a: function(){return 2} }
obj4.a=function(){return 3}
console.log(obj3); // Object { b: 1, a: function(){return 1} }
console.log(obj4); // Object { b: 1, a: function(){return 3} }
obj4.b=3;
console.log(obj3); // Object { b: 1, a: function(){return 1} }
console.log(obj4); // Object { b: 3, a: function(){return 3} }示例四
let obja={a:null,b:undefined,c:NaN,d:false,e:0,f:'',g:{e:1,f:2},h:new Date('2022-06-11'),j:function(){return 1;}};
function deepClone(obj){
let newObj;
if(obj == null || "object" != typeof obj) return obj; // 注意这里是"object",而不是"Object"。
if(obj instanceof Date){
newObj = new Date();
newObj.setTime(obj.getTime());
return newObj;
}
if(obj instanceof Array){
newObj = [];
let i;
for(i=0;i<obj.length;i++){
newObj[i]=deepClone(obj[i]); // 这里之所以不用push,是为了方便迭代深复制。
}
return newObj;
}
if(obj instanceof Function){
newObj=function(){
return obj.apply(this,arguments);
}
return newObj;
}
if(obj instanceof Object){
newObj={};
for(let item in obj){
if(obj.hasOwnProperty(item)){
newObj[item] = deepClone(obj[item]);
}
}
return newObj;
}
throw new Error("不支持复制的对象类型:"+obj.constructor.name);
}
let objb=deepClone(obja); // 深复制,不改变原对象。
objb.h= new Date('2022-06-12');
console.log(obja); // Object { a: null, b: undefined, c: NaN, d: false, e: 0, f: "", g: Object { e: 1, f: 2 }, h: Sat Jun 11 2022 08:00:00 GMT+0800 (中国标准时间), j: function(){return 1;} }
console.log(objb); // Object { a: null, b: undefined, c: NaN, d: false, e: 0, f: "", g: Object { e: 1, f: 2 }, h: Sun Jun 12 2022 08:00:00 GMT+0800 (中国标准时间), j: function(){return 1;} }
objb.j=function(){return 2;}
console.log(obja); // Object { a: null, b: undefined, c: NaN, d: false, e: 0, f: "", g: Object { e: 1, f: 2 }, h: Sat Jun 11 2022 08:00:00 GMT+0800 (中国标准时间), j: function(){return 1;} }
console.log(objb); // Object { a: null, b: undefined, c: NaN, d: false, e: 0, f: "", g: Object { e: 1, f: 2 }, h: Sun Jun 12 2022 08:00:00 GMT+0800 (中国标准时间), j: function(){return 2;} }边栏推荐
- Qt的模型与视图
- 如何做好固定资产管理?易点易动提供智能化方案
- Nacos - Configuration Management
- Personal decoration notes
- What is 1cr0.5mo (H) material? 1cr0.5mo (H) tensile yield strength
- Shell脚本-字符串
- AVL树的理解和实现
- TypeError: __init__() got an unexpected keyword argument ‘autocompletion‘
- 用C语言编程:用公式计算:e≈1+1/1!+1/2! …+1/n!,精度为10-6
- 【MFC开发(17)】高级列表控件List Control
猜你喜欢

《微机原理》-绪论

Redis publish subscription

Advanced level of C language pointer (Part 1)

《MATLAB 神经网络43个案例分析》:第30章 基于随机森林思想的组合分类器设计——乳腺癌诊断

VSYNC+三重缓存机制+Choreographer

What is the material of 16MnDR, the minimum service temperature of 16MnDR, and the chemical composition of 16MnDR

你了解数据是如何存储的吗?(C整型和浮点型两类)

FreeRTOS learning easy notes

What are the differences between the architecture a, R and m of arm V7, and in which fields are they applied?

The data analyst will be ruined without project experience. These 8 project resources will not be taken away
随机推荐
Only in China! Alicloud container service enters the Forrester leader quadrant
It is designed with high bandwidth, which is almost processed into an open circuit?
Shell脚本-for循环和for int循环
明明设计的是高带宽,差点加工成开路?
yolov5训练可视化指标的含义
动态代理
Memory size end
Nacos - Configuration Management
Li Kou 1358 -- number of substrings containing all three characters (double pointer)
Centos7 shell script one click installation of JDK, Mongo, Kafka, FTP, PostgreSQL, PostGIS, pgrouting
Programming with C language: calculate with formula: e ≈ 1+1/1+ 1/2! …+ 1/n!, Accuracy is 10-6
内存大小端
TypeError: __init__() got an unexpected keyword argument ‘autocompletion‘
《单片机原理与应用》——并行IO口原理
Shell脚本-case in 和正则表达式
基于Gazebo的无人机管道检测
C语言指针的进阶(下)
Insert mathematical formula in MD document and mathematical formula in typora
毕业季,我想对你说
如何解决固定资产管理和盘点的难题?