开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。
其实都是copy。javascript
深拷贝(递归复制,复制全部层级,独立副本,一个彻底和原来对象属性无关的副本)
返回对象:一个。
传入对象:一个。
条件:JSON安全的对象,能够序列化为JSON字符串,而且能够解析为新的字符串。
深拷贝算法:前端
function deepCopy(data){ let memory = null; const type = Object.prototype.toString.call(data); if (type === "[object Array]"){ memory = [] for (let i=0 ;i<data.length;i++){ memory.push(deepCopy(data[i])) } }else if (type === "[object Object]"){ memory = {} Object.keys[data].forEach((key)=>{ memory[key] = data[key] }) }else{ return data; } return memory; }
jQuery深拷贝:var copiedObject = jQuery.extend(true, {}, originalObject)
java
es6深拷贝:var copiedObject= JSON.parse(JSON.stringify(originalObject));
git
深拷贝是递归复制,新复制的对象与原对象是彻底独立的两个对象,它们指向不一样的内存地址,作set不会影响到对方。es6
浅拷贝(单次复制,复制最高层级,引用副本,一个基于对原对象属性引用的副本)
返回对象:一个。
传入对象:一个或多个。
条件:无。github
jQuery浅拷贝:var copiedObject = jQuery.extend({}, originalObject)
算法
es6浅拷贝:var copiedObject = Object.assign({},originalObject)
segmentfault
es7浅拷贝:var copiedObject = {...originalObject}
数组
浅拷贝算法:安全
function shallowCopyObj(original){ let copy = {} Object.keys(original).forEach(key=>{ copy[key] = original[key] }) return copy }
因为javascript的对象是存地址的,因此浅复制的对象与原对象,都指向同一个内存地址,属于引用复制,作set会影响到对方。
实验:
①普通属性修改:深拷贝和浅拷贝均可以知足对象的复制。
普通属性是指value值为非Array,Object类型的数据类型,也就是Number,String,Boolean等基本数据类型。
缘由:基本数据类型属于值传递。
var obj = {foo:1}; var deepCopyObj = JSON.parse(JSON.stringify(obj)); deepCopyObj.foo = 2; console.log("obj.foo:",obj.foo);//1 console.log("deepCopyObj.foo:",deepCopyObj.foo);//2
var obj = {foo:1}; var shallowCopyObj = Object.assign({},obj); shallowCopyObj.foo = 2; console.log("obj.foo:",obj.foo);//1 console.log("shallowCopyObj.foo:",shallowCopyObj.foo);//2
②高级属性修改:深拷贝知足对象的复制,浅拷贝影响原数组。
高级属性是指Array,Object数据类型。
缘由:基本数据类型属于引用传递。
var obj = {foo:1,bar:{baz:1}}; var deepCopyObj = JSON.parse(JSON.stringify(obj)); deepCopyObj.bar.baz = 2; console.log("obj.bar.baz:",obj.bar.baz);//1 console.log("deepCopyObj.bar.baz:",deepCopyObj.bar.baz);//2
var obj = {foo:1,bar:{baz:1}}; var shallowCopyObj = Object.assign({},obj); shallowCopyObj.bar.baz = 2; console.log("obj.bar.baz:",obj.bar.baz);//2 Attention! console.log("shallowCopyObj.bar.baz:",shallowCopyObj.bar.baz);//2
印象中const也是保持变量地址不变的操做,那么es6中的let和const对于对象的深浅拷贝有影响吗?
也就是将上面代码中的var替换为let和const。
实验结果是let和const不会影响深浅拷贝的结果,由于let强调块做用域,而const强调变量总体地址空间的不变性。
关于对象的深浅拷贝,暂且探索到这里,后续有新发现再进行补充。
谢谢您的阅读~
期待和你们交流,共同进步,欢迎你们加入我建立的与前端开发密切相关的技术讨论小组:
- SegmentFault技术圈:ES新规范语法糖
- SegmentFault专栏:趁你还年轻,作个优秀的前端工程师
- 知乎专栏:趁你还年轻,作个优秀的前端工程师
- Github博客: 趁你还年轻233的我的博客
- 前端开发QQ群:660634678
- 微信公众号: 人兽鬼 / excellent_developers
努力成为优秀前端工程师!