深浅拷贝
浅拷贝和深拷贝只针对引用类型
浅拷贝
浅拷贝:拷贝的是地址
如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响
拷贝对象之后,里面的属性值是简单数据类型直接拷贝值
如果属性值是引用数据类型则拷贝的是地址
总结:
如果是简单数据类型拷贝值,引用数据类型拷贝的是地址 (简单理解: 如果是单层对象,没问题,如果有多层就有问题)
常见方法:
- 拷贝对象:Object.assgin() / 展开运算符 {...obj} 拷贝对象
- 拷贝数组:Array.prototype.concat() 或者 [...arr]
直接赋值和浅拷贝区别:
直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址
浅拷贝:如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响
// 浅拷贝:只拷贝最外面一层
const obj = {
uname : '小明',
age : 18,
gender : 'man',
color : ['red', 'green', 'yellow'],
family : {
mother : 'mama',
father : 'baba'
}
}
// const o = {}
// 基本类型,栈中存的是数据,拷贝的也是数据
// 引用数据类型,栈中存的是数据在内存中的地址,拷贝的也是地址
// 方法1:遍历
// 有该属性就修改属性值,没有该属性就添加属性
//// o['uname'] = obj['uname']
// for (const key in obj) {
// o[key] = obj[key]
// }
// 方法2:Object静态方法:assign:将后面对象中的成员添加到前面对象(修改/添加)
// Object.assign(o,obj)
// 方法3:扩展运算符
const o = {...obj}
// 如果是简单数据类型拷贝值,引用数据类型拷贝的是地址
// (简单理解: 如果是单层对象,没问题,如果有多层就有问题)
o.age = 20
o.color[0] = 'pink'
o.family.mother = '妈妈'
console.log(o, obj)
深拷贝
深拷贝:拷贝的是对象,不是地址
常见方法
通过递归实现深拷贝
函数递归:
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
简单理解:函数内部自己调用自己, 这个函数就是递归函数
递归函数的作用和循环效果类似
由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return
let num = 1
function fn () {
console.log(`第${num}次打印`)
if(num >= 6) {
return
}
num++
fn()
}
fn()
递归实现深拷贝
const obj = {
uname : '小明',
age : 18,
gender : 'man',
color : ['red', 'green', 'yellow'],
family : {
mother : 'mama',
father : 'baba'
}
}
const o = {}
// 利用递归
function deepCopy (newObj, oldObj) {
for (const key in oldObj) {
// oldObj[key] : 当前属性对应的属性值
// 必须先查看数组,因为数组属于对象,对象不一定是数组
// 查看原型链中是否包含数组
if (oldObj[key] instanceof Array){
// 如果oldObj[key] 是数组,那么newObj[key]也得是数组
newObj[key] = []
deepCopy(newObj[key], oldObj[key])
} else if (oldObj[key] instanceof Object){
// 如果oldObj[key] 是对象,那么newObj[key]也得是对象
newObj[key] = {}
deepCopy(newObj[key], oldObj[key])
}
else {
// 如果oldObj[key] 是基本数据类型,直接赋值
newObj[key] = oldObj[key]
}
}
}
deepCopy(o, obj)
o.age = 20
o.color[0] = 'pink'
o.family.mother = '妈妈'
conso
lodash/cloneDeep
利用js库 lodash里面的 _.cloneDeep()
语法:const o = _.cloneDeep(obj)
通过JSON.stringify()实现
利用JSON字符串转换
语法:const o = JSON.parse(JSON.stringify(obj))