function deepClone(source,target){
if(target===undefined){
switch(true){
case source instanceof Array:
target=new source.constructor();
break;
case source instanceof HTMLElement:
target=source.cloneNode(true);
break;
case source instanceof Date:
case source instanceof RegExp:
case source.__proto__.name==="TypeArray":
case source instanceof Map:
case source instanceof Set:
target=new source.constructor(source);
break;
case typeof source==="function":
var arr=source.toString().replace(/\n/g,"").match(/\((.*?)\)\s*\{(.*)\}/).slice(1);
target = new Function(arr[0],arr[1]);
break;
default:
target={}
}
}
//获取对象的所有属性名,包括不可枚举和Symbol,形成一个数组
var keys=Reflect.ownKeys(source);
for(var i=0;i<keys.length;i++){
//获取每个属性的描述对象
var desc=Object.getOwnPropertyDescriptor(source,keys[i]);
//判断这个属性是不是对象
if(desc.value instanceof Object){
//如果当前的属性是constructor跳出不复制,复制会造成堆栈上限溢出
if(keys[i]==="constructor") continue;
//这里完全复制这个对象
Object.defineProperty(target,keys[i],{
enumerable:desc.enumerable,
configurable:desc.configurable,
writable:desc.writable,
//递归获取复制新的对象赋值给value
value:deepClone(desc.value)
})
//如果当前属性是prototypr时,在当前prototype属性下新增一个constructor属性是当前构造函数
if(keys[i]==="prototype"){
Object.defineProperty(target,"constructor",{
value:target
})
}
}else{
//如果这个描述对象的值不是引用类型,直接将这个属性的描述对象设置给新的目标对象中
Object.defineProperty(target,keys[i],desc);
}
}
return target;
}
封装深复制函数
最新推荐文章于 2024-08-05 17:32:31 发布