传智播客旗下技术交流社区北京校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

在js中,一切皆对象(null和undefined有待另外的理解),JavaScript 中的几乎所有对象都是位于原型链顶部 Object 的实例。

对象的基本的一些操纵,我们是必须要知道的。



  • let obj = {



  •   a: 1,



  •   b: 2,



  • };



  • let copy = obj;



  • copy.a = 5;



  • console.log(obj.a); // ==> 5


上面的代码应该都能理解,赋值运算符不会创建一个对象的副本,它只分配一个引用,

那我们就想到了,循环遍历对象



  • var obj = { a:1, arr: [2,3] };



  • var shallowObj = shallowCopy(obj);



  • function shallowCopy(src) {



  •   var dst = {};



  •   for (var prop in src) {



  •     if (src.hasOwnProperty(prop)) {



  •       dst[prop] = src[prop];



  •     }



  •   }



  •   return dst;



  • }



  • shallowObj.a = 4  ==>  obj.a =1



  • shallowObj.arr[1] = 5 ==> obj.arr[1] = 5


显然上面的遍历是起了一定的效果的,但是这只能算对象的浅拷贝(shallow copy),原因:因为浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅拷贝会导致 obj.arr 和 shallowObj.arr 指向同一块内存地址。

那改变一下上面的代码,我们需要用迭代来实现对对象的深拷贝(deep copy)



  • var obj = { a:1, arr: [2,3] };



  • var deepObj = deepCopy(obj);



  • function deepCopy(obj) {



  •         var newObj = obj.constructor === Array ? [] : {}



  •         if (typeof obj !== 'object') {



  •                 return



  •         } else {



  •                 for (var i in obj) {



  •                         if (obj.hasOwnProperty(i)) {



  •                 // 判断子元素是否为对象



  •                                 newObj = typeof obj === 'object' ? deepCopy(obj) : obj



  •                         }



  •                 }



  •         }



  •         return newObj



  • }



  • deepObj.arr[1] = 5



  • console.log(obj.arr[1])  ==> 3


解释:知乎网友的解释

对于字符串类型,浅复制是对值的复制,对于对象来说,浅复制是对对象地址的复制,并没 有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变,而深复制则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。

项目中,我也遇到Object.assign({},obj) 这种浅拷贝与JSON.parse(JSON.stringfy(obj))这种深拷贝,但是JSON.parse(JSON.stringfy(obj)) 这种方法是有缺陷的,其并不能复制,对象中的方法,但是Object.assign({},obj)可以。



  • let obj = {



  •   name: 'demo',



  •   test: function test() {



  •     return true;



  •   },



  • }







  • let method1 = Object.assign({}, obj);



  • let method2 = JSON.parse(JSON.stringify(obj));







  • console.log(method1);



  • /* result



  • {



  •   test: function test() {



  •     return true;



  •   },



  •   name: "demo"



  • }



  • */







  • console.log(method2);



  • /* result



  • {



  •   name: "demo"



  • }



  • */


最后,我也看到了一篇文章,《深入剖析 JavaScript 的深复制》,涉及到 jQuery, underscore, lodash 等库关于深复制的实现,有兴趣可以看看。


分享至 : QQ空间
收藏

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马
关闭

站长推荐 上一条 /5 下一条