/*
深拷贝:一、JSON.parse(JSON.stringify(obj))
JSON.stringify:对象序列化;JSON.parse:反序列化js对象
问题:1.obj存在时间对象的话,JSON.parse(JSON.stringify(obj))后会变成字符串,就无法使用new Date的其他方法如getFullYear()
2.存在RegExp、Error对象,序列化后变成空对象
3.存在函数、undefined,序列化后会丢失
4.存在NaN、Infinity,序列化后会变成null
5.JSON.stringfy()只能序列化对象的可枚举的自有属性,如obj的对象是由构造函数生成的,则JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor
二、deepClone
三、lodash:_.cloneDeep(obj)
*/
/*
浅拷贝:Object.assign()、扩展运算符、concat、slice、
*/
// 深拷贝
function deepClone(source) {
const targetObj = source.constructor === Array ? [] : {}
for (let keys in source) {
if (source.hasOwnProperty(keys)) {
if (source[keys] && typeof source[keys] === 'object') {
// 引用数据类型
targetObj[keys] = deepClone(source[keys])
} else {
// 基本数据类型
targetObj[keys] = source[keys]
}
}
}
return targetObj
}
const obj = {
name: 'obj',
js: {
name: '深拷贝',
},
age: [1, 2, 3]
}
const copyObj = deepClone(obj)
copyObj.name = '深拷贝2'
console.log(obj, copyObj)
// 问题1:存在时间对象的话,JSON.parse(JSON.stringify(obj))后会变成字符串
const obj1 = {
date: new Date(),
}
const copyObj1 = JSON.parse(JSON.stringify(obj1))
// console.log(copyObj1.date.getFullYear()) // =>报错
// 问题2:存在RegExp、Error对象,序列化后变成空对象
const obj2 = {
name: 'test',
reg: new RegExp('\\w+'),
error: new Error(123)
}
const copyObj2 = JSON.parse(JSON.stringify(obj2))
// console.log(copyObj2)
function eavl() {
try {
throw copyObj2.error
} catch (e) {
// console.log("问题2:", e.message) // =>清空后打印为undefined
}
}
eavl()
// 问题3:存在函数、undefined,序列化后会丢失
const obj3 = {
name: undefined,
getInfo: function getPersonInfo() {
console.log('123')
},
age: 10
}
const copyObj3 = JSON.parse(JSON.stringify(obj3))
// console.log(obj3, copyObj3)
// 问题4:存在NaN、Infinity,序列化后会变成null
const obj4 = {
name: Number('a'),
infinity: 1 / 0,
age: 12
}
const copyObj4 = JSON.parse(JSON.stringify(obj4))
// console.log(obj4, copyObj4)
// 问题5:JSON.stringfy()只能序列化对象的可枚举的自有属性,如obj的对象是由构造函数生成的,则JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor
function Person(name) {
this.name = name
}
const jsrun = new Person('jsrun')
const obj5 = {
name: 'obj5',
jsrun: jsrun
}
const copyObj5 = JSON.parse(JSON.stringify(obj5))
// console.log(obj5, copyObj5)
console