一、如何把一个对象复制给另一个对象
1.Object.assign()
let target = {}
let source = {
a: 1,
b: 2
}
Object.assign(target,source)
console.log(target)
// {a: 1, b: 2}
2.Object.assign() 只能实现浅拷贝
let target = {
a: {
b:1,
c: 8
}
}
let source = {
a: {
b:2
}
}
Object.assign(target,source)
console.log(target)
/*
{
"a": {
"b": 2
}
}
*/
// c 合并时丢失了
PS: 当两个对象其中一个对象,有两层或以上的结构时,Object.assign() 复制合并是有缺陷
二、深拷贝与浅拷贝
1. 浅拷贝:A对象拷贝了B对象的引用地址,两者最终指向同一块内存空间,所以任意对象值发生改变,都会改变内存空间的值
生活例子:我使用支付宝绑定了银行卡A,这时候给老婆的支付宝开通亲情卡绑定了银行卡A,
两个对象指的银行卡和亲情卡,不用的引用地址指的两个支付宝账号绑定渠道,最终指向银行卡A里面的钱,当我或老婆每次花一笔钱,银行卡A里面值都会发生改变。
生活例子:在线共享execl表格,每次拷贝就是复制URL,打开线上execl表格,每个人修改保存,都会同步更新给其他人。
let obj1 = {
name: 'xiao'
}
let obj2 = obj1
console.log(obj1)
// {name: 'xiao'}
obj1.name = 'guo'
console.log(obj2)
// {name: 'guo'}
2. 深拷贝: A对象拷贝了B对象的值,创造了新的内存空间,两者的值改变时互不影响
PS: 当前对象 指的 基本数据类型 和 对象
let a = 5
let b = a
a = 6
console.log(a, b)
三、 如何实现深拷贝
1. 通过对象和字符串之间的转换
- JSON.parse() 把json字符串 转换为 json对象
- JSON.stringify() 把json对象转换json字符串
let obj1 = {name: '张三'}
// 转换为json字符串
let str = JSON.stringify(obj1)
let obj2 = JSON.parse(str)
obj1.name = '赵四'
console.log(obj2)
// {name: '张三'}
2. 自定义深拷贝函数
// 检测数据类型
let checkType = data => {
let type = Object.prototype.toString.call(data)
// 从索引8开始截取,一直到结束
type = type.slice(8, -1)
return type
}
// 深拷贝
let deepClone = target => {
let targetType = checkType(target)
let result
if (targetType === 'Object') {
result = {}
} else if (targetType === 'Array') {
result = []
} else {
return target
}
for(let i in target) {
let value = target[i]
let valueType = checkType(value)
if (valueType === 'Object' || valueType === 'Array') {
result[i] = deepClone(value) // 递归
} else {
result[i] = value
}
}
return result
}
// 数组测试
let arr1 = [1, 2, {age:18}]
let arr2 = deepClone(arr1)
arr2[2].age= 34
console.log(arr1)
/*
[
1,
2,
{
"age": 18
}
]
*/
// 对象测试
let obj1 = {
name: 'xiaoxiao',
hobby: ['游戏', '羽毛球']
}
let obj2 = deepClone(obj1)
obj2.hobby[0] = '睡觉'
console.log(obj1)
/*
{
"name": "xiaoxiao",
"hobby": [
"游戏",
"羽毛球"
]
}
*/
console.log(obj2)
/*
{
"name": "xiaoxiao",
"hobby": [
"睡觉",
"羽毛球"
]
}
*/