JS中深拷贝和浅拷贝记录及解决方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS中深拷贝和浅拷贝记录及解决方法相关的知识,希望对你有一定的参考价值。

 这是本人第一次写博客。。。好紧张,有什么固定格式麽,需要爆照麽。。怎样才能让自己表现的不是第一次啊。。

不多说,最近一不小心就跳入一个坑,也是怪我自己知识点扩展不够。。这次记录下,上代码

/*a 原来的数组
* b 复制后的新数组
* */
function copy(a,b) {
for(var i=0;i<a.length;i++)
{
b.push(a[i])
}
}
var arr1=[1,2,3,4,5];
var arr2=[];
copy(arr1,arr2);
console.log(arr2);

输出结果:

技术分享

可以看到,这里的arr2和arr1现在一样,现在如果改变arr2中的某一个值,看看会不会影响到arr1

arr2[0]=100;
console.log(arr2)

输出结果:

技术分享

从结果可以看出,虽然改变了arr2但是arr1数组的值没有改变。
因为这里是基本数据类型,存于栈中。复制的时候,直接复制的是arr1的值给arr2.所以就算改变了arr2,arr1也不会改变的。但是如果arr1中含有对象呢。那么问题来了,这就是我进的坑
 
再来个栗子:
 
var arr3=[{name:‘张三‘},{age:22},{sex:‘男‘}];
var arr4=[];
copy(arr3,arr4);//复制arr3的值
console.log(arr3);
console.log(arr4);
 
输出结果为:
 

技术分享

上图是复制arr3到arr4中的结果,下图改变arr4[0].name=‘李四‘的结果
 
技术分享
 
此时,我发现我修改的是arr4的数组的值,为什么arr3的值也会改变呢,后来查了些资料发现  (以下为百度的资料)
 
浅拷贝
   浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。

 

技术分享

 

 在图中,SourceObject有一个int类型的属性 "field1"和一个引用类型属性"refObj"(引用ContainedObject类型的对象)。当对SourceObject做浅拷贝时,创建了CopiedObject,
它有一个包含"field1"拷贝值的属性"field2"以及仍指向refObj本身的引用。由于"field1"是基本类型,所以只是将它的值拷贝给"field2",但是由于"refObj"是一个引用类型,
所以CopiedObject指向"refObj"相同的地址。因此对SourceObject中的"refObj"所做的任何改变都会影响到CopiedObject。

深拷贝

深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

技术分享

在上图中,SourceObject有一个int类型的属性 "field1"和一个引用类型属性"refObj1"(引用ContainedObject类型的对象)。当对SourceObject做深拷贝时,创建了CopiedObject,它有一个包含"field1"拷贝值的属性"field2"以及包含"refObj1"拷贝值的引用类型属性"refObj2" 。因此对SourceObject中的"refObj"所做的任何改变都不会影响到CopiedObject


解决办法:

1.对象只有一层的话可以使用 Object.assign()函数;
var person1={name:‘小王‘,age:22,sex:‘男‘}
var person2=Object.assign({},person1);
person2.name=‘小李‘;
console.log(person1);
console.log(person2);
输出结果:

技术分享

2.转成 JSON 再转回来

JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。

var arr3=[{name:‘张三‘},{age:22},{sex:‘男‘}];
var arr4=JSON.parse(JSON.stringify(arr3));
arr4[0].name=‘李四‘;
console.log(arr3);
console.log(arr4);

输出结果:

技术分享

 

 

以上是简单的方法,这里记录了更多的方法。

http://www.cnblogs.com/Chen-XiaoJun/p/6217373.html

第一次写,喷吧。。轻点儿。。














































以上是关于JS中深拷贝和浅拷贝记录及解决方法的主要内容,如果未能解决你的问题,请参考以下文章

c++中深拷贝和浅拷贝问题

浅析Python中深拷贝和浅拷贝

java中深克隆与浅克隆的区别

python的复制,深拷贝和浅拷贝的区别

C++中,啥是深拷贝?啥是浅拷贝?

js实现深拷贝