原文:http://www.cnblogs.com/xie-zhan/p/6020954.html
JavaScript实现继承的时候,需要进行对象的拷贝;而为了不影响拷贝后的数据对原数据造成影响,也就是存在共享关系的时候,我们就需要进行深拷贝;
这里就做一个简单的分析其实现原理
先上代码:
var obj1 = { name : 'Awen', song : { auther : '小明', title : '广州' }, hobby: ['吃','吃吃','吃吃吃'] }; var obj2 = {}; for (var k in obj1) { obj2[k] = obj1[k]; } console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[3]} obj2['hobby'].push('喝'); console.log(obj1); //Object {name: "Awen", song: Object, hobby: Array[4]} console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[4]}
从图中得到结论:浅拷贝不能完成需求,对于属性是对象的时候,只是进行简单的地址拷贝,其引用关系也在;不符合我们的要求;
在来看下深拷贝:
function inCopy(obj1,obj2) { var obj1 = obj1 || {};//容错处理 for (var k in obj2) { if(obj2.hasOwnProperty(k)){ //只拷贝实例属性,不进行原型的拷贝 if(typeof obj2[k] == 'object') { //引用类型的数据单独处理 obj1[k] = Array.isArray(obj2[k])?[]:{}; inCopy(obj1[k],obj2[k]); //递归处理引用类型数据 }else{ obj1[k] = obj2[k]; //值类型的数据直接进行拷贝 } } } }
//深拷贝 两者之间改变互不影响
//1 拷贝后两者之间不再存在共享关系
//2 拷贝之后数据类型不能发生改变,也就是需要判断是数组的时候,需要进行单独递归的遍历
//3 在继承的时候,我们通过原型属性实现原型对象属性的继承,在进行深拷贝的时候,我们首先需要提出原型对象上的属性;通过hasOwnProperty方法来进行筛选;
测试代码及结果如下
var obj3 = { name : 'Awen', song : { auther : '小明', title : '广州' }, hobby : ['吃','吃吃','吃吃吃'] }; var obj4 = {}; inCopy(obj4,obj3); console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]} console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[3]} obj4.hobby.pop(); console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]} console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[2]} obj4.song.title = '北京'; console.log(obj3); console.log(obj4);
obj4动态改变
3 拷贝后数据类型保持一致
数据类型未发生改变
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了