深克隆:如果属性是基本类型,克隆的就是基本类型的值;如果属性是内存地址(引用类型),比如数组或者类对象,深克隆会新建一个对象空间,然后克隆里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。
浅克隆:如果属性是基本类型,克隆的就是基本类型的值;如果属性是内存地址(引用类型),克隆的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
直接赋值
直接赋值的话不管是复杂数据类型以及简单数据类型,操作数据时都会相互影响!
代码演示
let obj = {
uname: '张三',
age: 18,
hobby: ['篮球', '跑步']
}
let copyObj = {}
// 直接赋值
copyObj = obj
console.log(copyObj)
打印copyObj如下
修改copyObj里面的元素并打印
let obj = {
uname: '张三',
age: 18,
hobby: ['篮球', '跑步']
}
let copyObj = {}
// 直接赋值
copyObj = obj
console.log(copyObj)
// 修改copyObj里面的元素
copyObj.uname = '李四'
console.log(obj)
console.log(copyObj)
可以看出修改完copyObj的元素后,obj的元素也变化了,相互影响,满足不了我们需求
浅克隆 利用for in 遍历以及 Object.assign({},obj )
浅拷贝在执行完毕后在处理简单数据类型时,使用没有问题,但是在处理复杂数据类型时,会给复杂数据类型的地址给克隆对象,在修改克隆出来对象里面的复杂数据对象的属性时,会连带着给克隆对象的一块修改
for in遍历obj,给copyObj赋值,然后修改copyObj对象下面的uname以及hobby
let obj = {
uname: '张三',
age: 18,
hobby: ['篮球', '跑步'],
sayHi() {
console.log('HI');
}
}
let copyObj = {}
// for in遍历对象
for (let key in obj) {
//将obj[key]都赋值给copyObj[key]
copyObj[key] = obj[key]
}
console.log(copyObj);
// 修改copyObj里面的属性
copyObj.hobby.push('唱歌')
console.log(copyObj, obj);
代码运行后 copyObj修改复杂数据类型的数据影响了obj的数据,但是修改简单数据类型没有影响obj;
使用Object.assign({},obj)进行克隆
Object.assign({},obj)是将目标的属性和方法都赋值到一个目标对象中!如下就是将obj的属性和方法复制到一个空对象中并返回一个新的对象
let obj = {
uname: '张三',
age: 18,
hobby: ['篮球', '跑步'],
sayHi() {
console.log('HI');
}
}
let copyObj = Object.assign({}, obj)
console.log(copyObj);
copyObj.uname = '李白'
copyObj.hobby.push('唱歌')
console.log(copyObj, obj);
同样和for in 的方法一样,实现对象的克隆,但是复杂数据类型也会有影响
深克隆 使用JSON.parse 和JSON.stringify 以及Lodash进行克隆
// 深克隆
let obj = {
uname: '张三',
age: 18,
hobby: ['篮球', '跑步'],
sayHi() {
console.log('HI');
}
}
let jsonStr = JSON.stringify(obj)
let jsonObj = JSON.parse(jsonStr)
jsonObj.uname = '李白'
jsonObj.hobby.push('唱歌')
console.log(jsonObj, obj);
使用JSON.parse 和JSON.stringify 进行克隆修改复杂数据以及简单数据对源对象不会有影响,但是这个会给源对象里面的函数丢失!
使用Lodash 进行克隆
let obj = {
uname: '张三',
age: 18,
hobby: ['篮球', '跑步'],
sayHi() {
console.log('HI');
}
}
let copyObj = _.cloneDeep(obj);
copyObj.uname = '李白'
copyObj.hobby.push('唱歌')
console.log(copyObj, obj);
使用Lodashi里面的克隆可以完美的解决上面的问题,也是我们在开发中经常使用的方法!