一 使用扩展运算符
// 方法一: 扩展运算符深拷贝只能深拷贝拷贝一层,如果value是引用类型的则是浅拷贝
const obj1 = {
info: {
name: 'cgl',
age: 20
},
hobby: 'hhh'
}
const newObj = { ...obj1 }
newObj.info.name = 'wy'
newObj.hobby = 'ccc'
console.log('obj', obj1) // { info: {name: 'wy', age: 20}, hobby: 'hhh'}
console.log('newObj', newObj) // { info: {name: 'wy', age: 20}, hobby: 'ccc'}
二 使用JSON.parse和JSON.stringify
// 方法二:json-parse和json-stringify实现深拷贝
const obj7 = {
name: 'ccc',
arr: ['1', '2', '3']
}
const obj8 = JSON.parse(JSON.stringify(obj7))
obj7.name = 'ddd'
obj7.arr.splice(1, 1)
console.log('obj7--obj8', obj7, obj8)
// 但是json转换的方法有一个致命的缺陷,如果对象中有value的值是undefined,这样拷贝的时候会直接把value为undefined的键值对给删掉
const obj9 = {
name: 'ccc',
arr: ['1', '2', '3'],
address: undefined
}
const obj10 = JSON.parse(JSON.stringify(obj9))
obj9.name = 'ddd'
obj9.arr.splice(1, 1)
console.log('obj9--obj10', obj9, obj10)
三 使用递归函数进行深拷贝
// 1. 要拷贝的对象
const obj = {
name: "撩课",
age: 18,
friends: ["小花", "小黑"],
goodF: {
name: "小撩",
age: 19,
adress: "上海",
pets: [{ name: "土豆" }, { name: "马铃薯" }],
},
bir: new Date(),
}
// 判断是不是引用类型的数据
function isObj(obj) {
return obj instanceof Object
}
// 2.深拷贝函数: 对于键值对的值:如果是值类型,直接给键值对赋新值,如果是引用类型,就递归,直到递归到没有引用类型的value
// 思想: 遍历某个键值对的时候,值是引用类型的时候,先创建一个相同类型的空对象或者空数组,然后
function deepCopyObj2NewObj(fromObj, toObj) {
// 在函数中先检查第一个参数是否有值,
// 如果没有值那么就初始化一个空的对象
debugger
for (var key in fromObj) {
var fromValue = fromObj[key] // 获取到每一个键值对的value
// 判断value是不是一个引用类型
// 如果不是一个一个引用类型,直接就赋值就行了
if (!isObj(fromValue)) {
toObj[key] = fromValue
} else {
// 如果是引用类型,那么就再调用一次这个方法,去内部拷贝这个对象的所有属性
var temObj = new fromValue.constructor() // 通过这个方法创建fromValue对应的数据类型,是数组的话就创建一个空数组,是对象的话就创建一个空对象
deepCopyObj2NewObj(fromValue, temObj)
// 拷贝friends这个得时候,递归之后获取新的数组temObj,此时friends这个循环走完,接着把friend的循环走完
toObj[key] = temObj;
}
console.log('toobj', toObj)
}
}
var newObj = {}
deepCopyObj2NewObj(obj, newObj)
obj.goodF.pets[0]["size"] = "100px"
console.log(obj);
console.log(newObj);