首页 > 编程知识 正文

js如何实现深拷贝,js如何深拷贝

时间:2023-05-03 17:34:50 阅读:230176 作者:4383

    说到深浅拷贝的问题,其实就是基本类型和引用类型数据拷贝的问题,再深一点就是栈内存和堆内存的区别。

栈内存

    保存基本数据类型或者引用类型数据的地址指针。

堆内存

    保存对象本身。

    所谓的深拷贝就是在内存中单独为该变量开辟一个存储空间。所以对于基本数据类型来说他的任何赋值都深拷贝,因为在栈内存中,数据的大小是固定,不可变的,变量一旦声明就会在内存中在栈内存中开辟一个新的空间。常说的深拷贝是针对于引用类型的。引用类型在栈内存中只保存了一个指向堆内存的指针,所以一般我们在将一个引用类型赋值给另外一个变量的时候,实际上是将这个引用类型在栈内存中指针赋值给了这变量,而最终这个变量指向的堆内存中的同一个对象。

举例:

var obj1 = {name:"wangyy"};var obj2 = obj1;obj2.name="wangjunjie";console.log("obj1:",obj1);console.log("obj2:",obj2);运行结果:obj1:{name:"wangjunjie"} obj2:{name:"wangjunjie"}

    发现在改obj2的时候obj1也跟着改变了,这就是他们指针指向的是同一个内存对象,所以改也是改的同一个对象。但这不是我们希望的赋值 ,我们希望在赋值结束后彼此之前再无瓜葛,那我们应该怎样实现呢?
好了不多说了,上代码了。

方法一:

Object.assign();

var target = {};var source = {name:"wangyy"}Object.assign(target,source);target.name="wangjunjie";console.log("target:",target);console.log("source:",source);运行结果:target:{name:"wangjunjie"} source:{name:"wangyy"}

    貌似可以实现深拷贝,在这种情况下也确实能达到我们的目的,但是这种方式是有缺陷的,当对象的属性值也是一个对象的时候,它几现原形了。

var target = {};var source = {name:"wangyy",family:{mother:"wuxl","father":"wangxy"}}Object.assign(target,source);target.family.sister="wanghm";console.log("target:",target);console.log("source:",source);

    通过运行结果可以发现Object.assign只能对于像上面那种简单对象可以实现深拷贝,对于复杂对象就无能为力了。

方法二:

将对象转成字符串:

var target = {};var source = {name:"wangyy",family:{mother:"wuxl","father":"wangxy"}}target = JSON.parse(JSON.stringify(source ))target.family.sister="wanghm";console.log("target:",target);console.log("source:",source);

    哎!好像可以实现呢,而且也是想对比较号实现的。但是如果出爱心下面这种情况就凉凉了

var target = {};var source = { name:"wangyy", family:{ mother:"wuxl", father:"wangxy", } }target = JSON.parse(JSON.stringify(source ))target.family.sister="wanghm";console.log("target:",target);console.log("source:",source);

    运行后我们发现source中的func属性不见了。所以这种方式还是有局限性的,必须是标准格式的JSON数据。

方法三:

    看来向上面这种一步到位实现深拷贝是不显示了,那下面就专门写一个深拷贝的方法来实现:

function deepClone(data){ if(!data|!(datainstanceof Object)|(typeof data=="function")){ return data||undefined; } var constructor = data.constructor; var result = new constructor(); for(var key in data){ if(data.hasOwnProperty(key)){ result[key]=deepClone(data[key]); } } return result;}

本质就是区分基本数据类型和引用数据类型,然后进行递归操作,over!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。