const deepClone =(initalObj) =>
{
if (typeof initalObj !== 'object') {//如果是基本类型直接返回值
return initalObj
}
const obj = Array.isArray(initalObj)?[]:{};//可能是对象或者数组
for (const key in initalObj) {
if (typeof initalObj[key] === 'object') {//对于对象元素,deepclone
//递归返回新的对象
obj[key] = deepClone(initalObj[key]);
} else if (typeof initalObj[key] === 'function') {//对于函数,用bind拷贝
//返回新函数
obj[key] = initalObj[key].bind(obj);
} else {
//基本类型直接返回
obj[key] = initalObj[key];
}
}
return obj;
}
改进:
通过递归可以简单实现对象的深度克隆,但是这种方法不管是ES6还是ES5实现,都有同样的缺陷,就是只能实现特定的object的深度复制(比如数组和函数),不能实现包装对象Number,String , Boolean,以及Date对象,RegExp对象的复制。
下面是完美版的深拷贝
参考自:https://blog.csdn.net/liwusen/article/details/78759373
function istype(obj,type){//判断包装类型的原型
return Object.prototype.toString.call(obj).indexOf(type)!=-1
}
const deepClone =(initalObj) =>
{
if (typeof initalObj !== 'object') {//如果是基本类型直接返回值
return initalObj
}
if(istype(initalObj,'String')||istype(initalObj,'Number')||istype(initalObj,'Boolean'))
return initalObj.valueOf();
if(istype(initalObj,'Date'))
return new Date(initalObj.valueOf());
if(istype(initalObj,'RegExp')){
let pattern = initalObj.valueOf();
let flags = '';
flags += pattern.global ? 'g' : '';
flags += pattern.ignoreCase ? 'i' : '';
flags += pattern.multiline ? 'm' : '';
return new RegExp(pattern, flags);
}
const obj = Array.isArray(initalObj)?[]:{};//可能是对象或者数组
for (const key in initalObj) {
if (typeof initalObj[key] === 'object') {//对于对象元素,deepclone
//递归返回新的对象
obj[key] = deepClone(initalObj[key]);
} else if (typeof initalObj[key] === 'function') {//对于函数,用bind拷贝
//返回新函数
obj[key] = initalObj[key].bind(obj);
} else {
//基本类型直接返回
obj[key] = initalObj[key];
}
}
return obj;
}
测试
const obj = {
a: 1,
b: {b1:[],b2:[]},
c: { d: {}, g: () => {} },
e: () => {},
f: function() {}
}
const newObj = deepClone(obj);
console.log(newObj.a === obj.a);
console.log(newObj.b === obj.b);
console.log(newObj.c === obj.c);
console.log(newObj.c.d === obj.c.d);
console.log(newObj.c.g === obj.c.g);
console.log(newObj.e === obj.e);
console.log(newObj.f === obj.f);
const o2=deepClone([0,obj,[1]])
console.log(o2);
var str=new String("hello");
console.log(Object.prototype.toString.call(str))
console.log(deepClone(str));
console.log(Object.prototype.toString.call(new Number()))
console.log(deepClone(new Number(100)));
console.log(Object.prototype.toString.call(new Date()))
console.log(deepClone(new Date()));
console.log(Object.prototype.toString.call(new RegExp('/111/')))
console.log(deepClone(new RegExp('/111/')));