浅拷贝与深拷贝区别,手写实现深拷贝

143 阅读1分钟

前言

在了解深拷贝与浅拷贝之前,先说明一下js中的数据类型划分为2大类

基本类型

字符串(string),数值(number),布尔值(boolean),undefined ,null等

他们在内存中采用栈存取

引用类型

数组(Array),对象(object),函数(function)

这些数据在内存中采用堆的方式存取

浅拷贝与深拷贝

浅拷贝指的是某一个对象,当将其赋值给另一个变量时,如果是基本数据类型,就直接赋其中的值,如果是引用类型,就赋的是其地址。所以如果是引用数据类型使用浅拷贝,当其中一个变量变化时,另一个变量也会跟着变化

image.png

而深拷贝指的是将一个对象从内存中完整的复制到另一个变量上,且两个变量完全保持独立性

深拷贝实现

  function deepclone(target){
           let res=target.constructor===Array?[]:{};
           
           for(let key in target){ //依次遍历所有属性
           
               if(target[key]&&typeof target[key]==='object'){ //如果又是引用类型,做递归处理
                res[key]=deepclone(target[key]);
               }else{
                   res[key]=target[key]  //反之就直接赋值
               }
           }
           return res; 
       }

判断target的数据类型不使用typeof原因是:typeof对所有引用类型数据都会判断为object

最终版(解决循环引用以及其他主要数据类型问题)

 function deepClone(obj,hash=new WeakMap()){
            if(obj===null) return null;
            if(obj instanceof Date) return new Date(obj);
            if(obj instanceof RegExp) return new RegExp();
            if(hash.has(obj)) return hash.get(obj)
            if(typeof obj !=='object') return obj;
            let res=obj.constructor();
            hash.set(obj,res);
            for(let k in obj){
                res[k]=deepClone(obj[k],hash)
            }
            return res;
        }