在js中,若是一个对象,做为变量赋值给另外一个对象,那么两个对象得值会是相同得引用地址,其中一个改变,另一个也会随之改变。函数
`性能
var obj1 = {
num: 123
}
var obj2 = obj1;
obj2.num = 456;
console.log(obj1.num); // 输出: 456
复制代码
` 在咱们平常开发过程中,咱们去复制一个对象得目的是为了去得到该对象的值,咱们对得到的值进行操做,不会影响原对象才对。而咱们要解决这样的问题,就涉及到了使用对象的浅拷贝和深拷贝来解决问题了。spa
浅拷贝是咱们平常开发使用最多的,由于他能解决咱们平常开发中绝大部分的问题,首先最经常使用的方法就是:Object.assign()
,是ES6:Object里的新增方法,Object.assign()
方法用于对象的合并,将源对象(source)的全部可枚举属性,复制到目标对象(target),那么如何使用呢,请看案例:3d
`code
var obj1 = {
num: 123
}
var obj2 = Object.assign({}, obj1);
obj2.num = 456;
console.log(obj1.num, obj2.num); // 输出: 123 456
复制代码
`cdn
使用方法,仍是很是简单的,咱们也可使用扩展运算符...
的方法来实现浅拷贝: `对象
var obj1 = {
num: 123
}
var obj2 = {...obj1};
obj2.num = 456;
console.log(obj1.num, obj2.num); // 输出: 123 456
复制代码
` 所谓浅拷贝,实际上指的就是复制对象自己可枚举的属性,不会拷贝到继承属性和可自己可枚举属性的值也是对象里的值。blog
上面那句话的后半段里看上去有点绕,这里在讲什么是深拷贝,你就立马理解了。而 深 这个字我我的以为就挺通俗易懂了,说白了就是更深层次的拷贝呗。那么怎么就是深拷贝呢?看案例: `继承
var obj1 = {
num: 123,
child: {
str: '子级对象'
}
}
var obj2 = Object.assign({}, obj1);
obj2.child.str = '子对象的str值';
console.log(obj1.child.str); // 输出: 子对象的str值
复制代码
`开发
经过上面的案例,咱们发现,咱们用了浅拷贝,可是obj1
和obj2
里面的child
子对象仍是共用了一个引用地址,这就是我上面说的那句“自己可枚举属性里的值也是对象”,因此咱们就须要更深层次的拷贝到这个对象里来呗,这就须要使用深拷贝了,最多见的深拷贝方法就是:JSON.parse(JSON.stringify(obj1))
,下面看案例:
`
var obj1 = {
num: 123,
child: {
str: '子级对象'
}
}
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.child.str = '子对象的str值';
console.log(obj1.child.str); // 输出: 子级对象
复制代码
`
经过使用JSON.parse(JSON.stringify(obj1))
咱们实现了深拷贝,其实该方法的实现原理很是的简单,JSON.stringify()
是把咱们的对象转换成了JSON字符串,字符串属于基本类型了,已经不存在引用地址了,而后咱们在用JSON,pase()
把它转换回来,此时它已是一个新对象了,和原对象没有任何关系了。经过这样转换的方式实现了深拷贝。可是呢,该方法也存在必定的局限性,或者说是不足:
undefined
,下面看案例:
`
let obj = {
a: 1,
b: {
c: 2,
d: 3,
},
}
obj.c = obj.b
obj.e = obj.a
obj.b.c = obj.c
obj.b.d = obj.b
obj.b.e = obj.b.c
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj)
复制代码
`
若是你的对象像这样的相互引用赋值的话,那么你会发现不能使用JSON.parse(JSON.stringify(obj1))
来实现了,而且还报错:
undefined
和函数时,也不能正常实现深拷贝:
`
let obj1 = {
id: undefined,
fn: function() {},
tel: 13880089009
}
let obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj2) // {tel: 13880089009}
复制代码
`
这样只拷贝到了tel
一个属性值:那么这个时候就会用到经常使用得另外一种深拷贝方式了:for in
`
let obj1 = {
id: undefined,
fn: function() {},
tel: 13880089009
}
let obj2 = {}
for (let key in obj1) {
obj2[key] = obj1[key]
}
console.log(obj2) // {id: undefined, fn: ƒ, tel: 13880089009}
复制代码
`
for in
自己是一个比较耗性能得循环方法,它实现得方式也简单粗暴,就是一个属性一个属性得赋值,for in
还能够遍历到对象继承得全部属性和方法,正是由于这一点,因此for in
是个耗性能得主。
本篇章主要讲解得是浅拷贝和深拷贝这样得一个概念,并给出了我的用得一些浅拷贝和深拷贝得方法,用于对咱们平常开发当中注意得一些细节操做。喜欢得朋友给个赞吧,谢谢。