1.1 浅拷贝
把一个对象拷贝给新的对象(如果直接赋值,则复制的是对象地址,新对象修改时会导致旧的对象也同时改变);
1.2 拷贝对象
1.2.1 assign() 方法
Object.assign()
静态方法用于将一个或者多个源对象中所有可枚举的自有属性复制到目标对象。
const oldObj = {
name:'huihui',
age:18
}
const newObj = {}
Object.assign(newObj,oldObj);
1.2.2 展开运算符
const obj = {
name:'huihui',
age:19
}
const newObj = {...obj}
1.3 拷贝数组
1.3.1 concat() 方法
concat()方法用于连接两个或多个数组;不会更改现有数组,而是返回一个新数组。
const arr = ['hh','ff']
const arr1 = []
const newArr = arr1.concat(arr)
1.3.2 展开运算符
const arr = ['hh','ff']
const newArr = [...arr]
1.4 浅拷贝的问题
单层对象可以使用浅拷贝,但对于多层对象,使用浅拷贝会导致改变新的对象的值时会同时改变旧对象的值。如下:
const obj = {
name:'huihui',
student:{
name:'hh',
age:18
}
}
const newObj = {...obj}
newObj.student.name = 'huhu'
console.log(newObj.student.name) //huhu
console.log(obj.student.name) //huhu
因此,在遇到多层对象时,必须使用深拷贝。
2.1 深拷贝
可以拷贝多层对象,而不是简单拷贝地址。
2.2 JSON序列化
通过JSON.stringify()方法将对象序列化为字符串,再使用JSON.parse()方法将字符串转回对象格式。JSON.stringify() 序列化会忽略 function 和 undefined,因此当对象中包含undefined和函数时,不采用JSON序列化方法。
const obj = {
name:'huihui',
student:{
name:'hh',
age:18
}
}
const newObj = JSON.parse(JSON.stringify(obj))
2.3 lodash库实现
官网:lodash库
采用loadsh库中的_.cloneDeep()方法实现深拷贝
//引入lodash库
<script src='./js/lodash.min.js'></script>
<script>
const obj = {
name:'teacher',
student:{
name:'huihui',
age:18
},
changeName() {
console.log('teacher1');
}
}
const newObj = _.cloneDeep(obj)
</script>
2.4 递归函数实现
采用递归函数封装简易版_.cloneDeep(),只考虑对象内包含数据和对象的情况,如下:
function cloneDeep(oldObj) {
const newObj = Array.isArray(oldObj) ? [] : {}
for(let k in oldObj) {
if(typeof oldObj[k] === 'object')
newObj[k] = cloneDeep(oldObj[k]) //引用数据类型,需要递归进行拷贝
else
newObj[k] = oldObj[k] //基本数据类型直接赋值
}
return newObj
}