码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2017-05-19 20:20:14      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:for   简单   parse   style   lang   分配   创建   分享   代码   

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

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

/*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中深拷贝和浅拷贝记录及解决方法

标签:for   简单   parse   style   lang   分配   创建   分享   代码   

原文地址:http://www.cnblogs.com/cqkm/p/6880019.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!