当前位置:网站首页>通过 代码实例 理解 浅复制 与 深复制
通过 代码实例 理解 浅复制 与 深复制
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;} }边栏推荐
猜你喜欢

MATLAB小技巧(23)矩阵分析--模拟退火

It is designed with high bandwidth, which is almost processed into an open circuit?

【面试必刷101】链表

3、Modbus通讯协议详解
V79.01 Hongmeng kernel source code analysis (user mode locking) | how to use the fast lock futex (Part 1) | hundreds of blogs analyze the openharmony source code

SPL installation and basic use (II)

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

嵌入式工程师面试题3-硬件

What is 1cr0.5mo (H) material? 1cr0.5mo (H) tensile yield strength

Memory size end
随机推荐
《单片机原理及应用》—定时器、串行通信和中断系统
Share 7 books I read in the first half of 2022
电脑小技巧
Matlab [functions and images]
Redis publish subscription
【C】 Summary of wrong questions in winter vacation
Full mark standard for sports items in the high school entrance examination (Shenzhen, Anhui and Hubei)
我想知道手机注册股票开户的流程?另外,手机开户安全么?
Memory size end
【js逆向】md5加密参数破解
yolov5训练可视化指标的含义
1. Connection between Jetson and camera
【无标题】
如何做好固定资产管理?易点易动提供智能化方案
[MFC development (16)] tree control
How to use OKR as the leadership framework of marketing department
5mo3 UHI HII HII 17mn4 19Mn6 executive standard
Only in China! Alicloud container service enters the Forrester leader quadrant
3. Detailed explanation of Modbus communication protocol
深度学习训练样本扩增同时修改标签名称