开启辅助访问
帐号登录 |立即注册

JS的深拷贝与浅拷贝

 
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

1. 如果是基本数据类型,名字和值都会储存在栈内存中
var a = 1;
b = a; // 栈内存会开辟一个新的内存空间,此时b和a都是相互独立的
b = 2;
console.log(a); // 1

当然,这也算不上深拷贝,因为深拷贝本身只针对较为复杂的object类型数据。

2. 如果是引用数据类型,名字存在栈内存中,值存在堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值
比如浅拷贝:

当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值。

而当我们a[0]=1时进行数组修改时,由于a与b指向的是同一个地址,所以自然b也受了影响,这就是所谓的浅拷贝了。

那,要是在堆内存中也开辟一个新的内存专门为b存放值,就像基本类型那样,岂不就达到深拷贝的效果了。

浅拷贝:直接把对象的属性一一赋值,不考虑属性值类型
缺点:如果属性值为对象的时候,只要修改一个,其余对象对应数据都会改变

//浅拷贝
var stu1={};
stu1.name=stu.name;
stu1.age=stu.age;
stu1.hobby=stu.hobby;
stu1.score=stu.score;
//浅拷贝后,如果属性值为对象的时候,只要修改一个,其余对象对应数据都会改变
stu.hobby[0]="弹吉他";//stu和stu1的hobby:["弹吉他",'跳舞']
快速实现浅拷贝
var stu2={};
for(var i in stu){
stu2=stu;
}

深拷贝:如果对象的属性值为基本数据类型,直接拷贝。如果对象属性对应的值对象,需要解析对象,再去拷贝
// 快速实现深拷贝(函数递归调用)
function deepCopy(obj){
//先判断obj是数组还是对象
if(obj instanceof Array){
var newobj=[];
}else if(obj instanceof Object){
var newobj={};
}
//遍历obj
for(var i in obj){
//如果当前遍历的属性的是对象
if(obj instanceof Object){
//将当前属性作为参数再次调用deepCopy
newobj=deepCopy(obj);//递归
}else{
//如果是基本数据类型直接赋值
newobj=obj;
}
}
//返回深拷贝出的新对象
return newobj;
}

回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

友情链接
  • 艾Q网

    提供设计文章,教程和分享聚合信息与导航工具,最新音乐,动漫,游戏资讯的网站。