深浅拷贝概念
浅拷贝
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个 地址,就会影响到另一个对象。
深拷贝
会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即 发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。”
1、浅拷贝
name: 'ajax',
age: 18,
family: {
baby: '来自m78星云那美克星及北爱尔兰洛克王国皇家骑士学院的靓仔'
}
}
// 对象直接赋值后会相互影响
// const o = obj
// o.name = 'red'
// console.log(o.name, obj.name);//'red' 'red'
如果属性是基本类型,拷贝的就是基本类型的值,因此对象直接赋值后会相互影响
// 浅拷贝 一层对象o和obj不会互相影响 多层对象会影响
// const o = {...obj}
// o.age = 20
// console.log(o.age, obj.age); //20 18
// Object.assign(o, obj) 和 o = {...obj} 效果一样
const o = {}
Object.assign(o, obj)
o.age = 30
console.log(o.age, obj.age); //30 18
如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象
那么如何做到拷贝一个对象,并且拷贝的对象发送变化时不会影响源对象的数据呢? 那就要介绍一下深拷贝了
2、深拷贝
I、利用递归函数实现深拷贝
我们需要遍历旧对象,并判定对象元素类型 》如果对象为数组,再次循环赋值 》》判定对象为对象类型时再次循环赋值 》》》如果对象为简单数据类型,直接进行赋值
万物皆对象
const o = {}
function deepCopy(newobj, oldobj) {
for (let k in oldobj) {
if (oldobj[k] instanceof Array) {
// 当对象元素为数组时 再次循环赋值
// newobj[k]接受[]
newobj[k] = []
// oldobj[k] ['乒乓球', '足球']
deepCopy(newobj[k], oldobj[k])
} else if (oldobj[k] instanceof Object) {
// 因为数组也属于对象 所以要在对象前面判断
// 当对象元素为对象时 再次循环赋值
// newobj[k]接受{}
newobj[k] = {}
// oldobj[k] ['乒乓球', '足球']
deepCopy(newobj[k], oldobj[k])
} else {
// 对象元素不为数组则直接赋值
// newobj[k] 新对象的属性名 = 旧对象属性值
// k 属性名 oldobj[k]属性值
newobj[k] = oldobj[k]
}
}
}
deepCopy(o, obj)
o.age = 20
o.hobby[0] = '篮球'
console.log(o); //{uname: 'pink', age: 20, hobby:['篮球', '足球']}
console.log(obj); ////{uname: 'pink', age: 18, hobby:['乒乓球', '足球']}
II、利用lodash实现深拷贝 引入js文件
我们也可以利用lodash插件来完成深拷贝
// const o = _.cloneDeep(obj)
const obj = {
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球']
}
网址传送门```````````www.lodashjs.com
III、JSON实现深拷贝
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球'],
family: {
baby: '来自m78星云那美克星及北爱尔兰洛克王国皇家骑士学院的靓仔'
}
}
// 利用JSON实现深拷贝 先转换为JSON字符串 再转换为对象 则使新对象内容和旧对象一样 地址不一样
const o = JSON.parse(JSON.stringify(obj))
o.family.baby = '123'
console.log(o, obj);
后记
若发现内有语句或逻辑混乱的地方,还请各路大神指正。