手写要点:
- 递归
- 判断类型(非Object、Object)
- 检查环(对象有字段指向对象本身)
- 不拷贝原型上的属性
string、number、bool、null、undefined、symbol、bigint
Date、函数、数组、正则
开始手写
const cache = new Map();
const deepClone = (a)=>{
if(cache.get(a)){
return cache.get(a);
}
if(a instanceof Object){
let result;
if(a instanceof Function){
if(a.prototype){//如果是普通函数
result = function(){ return a.apply(this,arguments) }
}else{//箭头函数
result = (...args)=>a.call(undefined,...args)
}
}else if(a instanceof Array){
result = []
}else if(a instanceof Date){
result = new Date(a-0)//时间戳
}else if(a instanceof RegExp){
result = new RegExp(a.source,a.flags);
}else{
result = {}
}
cache.set(a,result);
for(let k in a){
if(a.hasOwnProperty(k)){
result[k] = deepClone(a[k]);
}
}
return result;
}else{
return a;
}
}
const a = {
number: 1,
bool: false,
str: 'hi',
empty1: undefined,
empty2: null,
array: [
{name: 'tian',age: 11},
{name: 'yang',age: 22}
],
date: new Date(2000,0,1,20,30,0),
reg: /\.(j|t)sx/i,
obj: {name: 'ttt'},
f1: (a,b)=>a+b,
f2: function(a,b){return a-b},
}
a.self = a;
const b = deepClone(a);
打印b是没有问题的