原生js手写深拷贝实现

79 阅读1分钟

手写要点:

  1. 递归
  2. 判断类型(非Object、Object)
  3. 检查环(对象有字段指向对象本身)
  4. 不拷贝原型上的属性
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是没有问题的