深度拷贝
1. 迭代递归法 (函数没有拷贝)
let test = {
num: 0,
str: '',
boolean: true,
unf: undefined,
nul: null,
obj: {
name: '我是一个对象',
id: 1
},
arr: [0, 1, 2],
func: function() {
console.log('我是一个函数')
},
date: new Date(0),
reg: new RegExp('/我是一个正则/ig'),
err: new Error('我是一个错误')
}
function isObject(o){
return o instanceof Object;
}
let result = deepClone(test)
console.log(result)
for (let key in result) {
if (isObject(result[key]))
console.log(`${key}相同吗? `, result[key] === test[key])
}
function deepClone(obj){
if(!isObject(obj)){
throw new Error(obj+" 不是对象")
}
let isArr = Array.isArray(obj);
let cloneObj = isArr?[]:{};
for(let key in obj){
cloneObj[key] = isObject(obj[key])?deepClone(obj[key]):obj[key];
}
return cloneObj;
}
// 代理法
function deepClone(obj) {
if (!isObject(obj)) {
throw new Error('obj 不是一个对象!')
}
let isArray = Array.isArray(obj)
let cloneObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(cloneObj).forEach(key => {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return cloneObj
}
/*结果
{ num: 0,
str: '',
boolean: true,
unf: undefined,
nul: null,
obj: { name: '我是一个对象', id: 1 },
arr: [ 0, 1, 2 ],
func: {},
date: {},
reg: {},
err: {} }
obj相同吗? false
arr相同吗? false
func相同吗? false
date相同吗? false
reg相同吗? false
err相同吗? false
*/
3. 序列化反序列化法
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj))
}
/*
{ num: 0,
str: '',
boolean: true,
nul: null,
obj: { name: '我是一个对象', id: 1 },
arr: [ 0, 1, 2 ],
date: '1970-01-01T00:00:00.000Z',
reg: {},
err: {} }
obj相同吗? false
arr相同吗? false
reg相同吗? false
err相同吗? false
*/
它也只能深拷贝对象和数组,对于其他种类的对象,会失真。这种方法比较适合平常开发中使用,因为通常不需要考虑对象和数组之外的类型。