浅拷贝
ES5浅拷贝
- 浅拷贝主要是对于同一个数据地址的拷贝过程,在将a拷贝给b的过程中,并没有给b单独开放内存,只是将a数据的指针拷贝给了b
- 所以不论a和b谁改变了,另一个元素都会改变
- 我们可以进行尝试:
编辑一个copy.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>深拷贝</title>
</head>
<body>
<p>一段文字</p>
<script src="./shallowCopy.js"></script>
</body>
</html>
在编辑引入的shallowCopy.js文件
let o = {}
let obj = {
age: 20,
name: 'xxx',
address:{
city:'beijing'
},
arr:['a','b','c']
}
o = obj
console.log("o",o)
o.address.city = "shanghai"
o.age = 21
console.log("obj",obj)
输出结果如下:
可以看到obj中的age和city字段都随着o的改变而改变了
ES6浅拷贝
ES6实现浅拷贝用的是Object.assign()方法
如下我们改变shallowCopy.js文件
let obj = {
age: 20,
name: 'xxx',
address:{
city:'beijing'
},
arr:['a','b','c']
}
/let es = Object.assign({},obj)
es.address.city="xian"
es.age = 23
console.log("es",es)
console.log("obj",obj)
仔细看,结果是这样的:
可以看到address中的city发生了改变,但是age并没有改变
官方给出的说明是:
Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象
说明,对于obj直接的属性是拷贝了数据,但是再深层的就没办法了
那么再深层的怎么办呢,我们使用深拷贝
深拷贝
直接看代码:
copy.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>深拷贝</title>
</head>
<body>
<p>一段文字</p>
<script src="./deepCopy.js"></script>
</body>
</html>
deepCopy.js
//深拷贝
console.log("深拷贝")
const obj = {
age: 20,
name: 'xxx',
address:{
city:'beijing'
},
arr:['a','b','c']
}
const obj2=deepClose(obj)
obj2.address.city="xian"
obj2.age = 23
console.log("obj2",obj2);
console.log("obj", obj);
/*
* 深拷贝
* @param {object} obj2 要拷贝的对象
* */
function deepClose(obj2 = {}) {
if (typeof obj2 !== 'object' || obj2 === null){
//obj2是null,或者不是对象和数组,直接返回
return obj2
}
//初始化返回结果
let result
if (obj2 instanceof Array){
result = []
}else {
result = {}
}
for (let key in obj2){
if (obj2.hasOwnProperty(key)) {
//保证key不是原型的属性
//递归调用
result[key] = deepClose(obj2[key])
}
}
//返回结果
return result
}
结果
可以看到,不论是一层嵌套,还是深层嵌套,都没有改变。
- 我们可以发现深拷贝是通过递归来实现的,对每一层的元素,如果还有更深层的嵌套就递归
- 所以我们所有的数据都跑到了最深层,然后再进行拷贝,就可以拷贝所有的数据,而不是地址,从而独立两个对象。