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='李四' arr3的结果
![](https://images2015.cnblogs.com/blog/1112131/201705/1112131-20170519190441682-1853550102.png)
此时,我发现我修改的是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.stringify 再转回JSON.parse
用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
第一次写,喷吧。。轻点儿。。