手写一个深拷贝

147 阅读2分钟

深拷贝是一面试的重点,要理解深拷贝的原理

工作当中最常见的深拷贝,能解决大部分的问题,就是JSON序列化

const a = {name: '张三'}
const b = JSON.parse(JSON.stringify(a))
console.log(a===b)// false

但是在面试的时候面试官一般会让你手写一个深拷贝,这个时候就要理解深拷贝的原理了

先封装一个函数.判断传入的数据是否为null还是为object,不为object或者是null 直接返回

 function deepClone(obj = {}) {
  // 判断传入的数据是否为null  或者是否为 object  不为object或者是null 直接返回
        if (typeof obj !== 'object' || obj == null) {
            return obj
        }
 
 }
 
 // 测试
 const  a=44
 const b= deepClone(a)
 console.log(b) // 44
 

判断初始数据的类型是否为数组,是数组返回空数组,不是数组返回空对象

    function deepClone(obj = {}) {
       // 判断传入的数据是否为null  或者是否为 object  不为object或者是null 直接返回
        if (typeof obj !== 'object' || obj == null) {
            return obj
        }
        
        //  定义变量接收判断的值
        let  result 
        // 判断初始传入的数据是否为数组,是数组返回空数组,不是返回空对象
        if(obj  instanceof  Array){
             result=[]
        }else{
             result={}
        }
        
        // 返回结果
        return  result
 }
 
 //  测试
 const  c= [3443,343434]
 const  d =deepClone(c)
 console.log(d)  // []
 

使用for in 循环遍历数组或对象的每一项,判断是否为原型上的属性,根据obj.hasOwnproperty()进行判断,对每一项进行递归,根据不同的类型添加到result,返回结果

      function deepClone(obj = {}) {
       // 判断传入的数据是否为null  或者是否为 object  不为object或者是null 直接返回
        if (typeof obj !== 'object' || obj == null) {
            return obj
        }
        
        //  定义变量接收判断的值
        let  result 
        // 判断初始传入的数据是否为数组,是数组返回空数组,不是返回空对象
        if(obj  instanceof  Array){
             result=[]
        }else{
             result={}
        }
        for(let key in obj){
            // 判断是否为原型上的属性
          if(obj.hasOwnProperty(key)){
              // 递归调用  对每一项进行递归遍历.判断类型,根据不同的类型返回不同的结果添加到result中
              result[key]=deepClone(obj[key])
          }
        };
        // 返回结果
        return  result
 }
 

完整代码

    function deepClone(obj = {}) {
        // 判断传入的数据是否为null  或者是否为 object  不为object或者是null 直接返回
        if (typeof obj !== 'object' || obj == null) {
            return obj
        }
        //  定义变量接收判断的值
        let  result 
        // 判断初始传入的数据是否为数组,是数组返回空数组,不是返回空对象
        if(obj  instanceof  Array){
             result=[]
        }else{
             result={}
        }

        for(let key in obj){
            // 判断是否为原型上的属性
          if(obj.hasOwnProperty(key)){
              // 递归调用  对每一项进行递归遍历.判断类型,根据不同的类型返回不同的结果添加到result中
              result[key]=deepClone(obj[key])
          }
        };
        // 返回结果
        return  result

    }
    const  obj ={
        name:'李四',
        age:13,
        hobby:['吃饭','睡觉']
    }
    const a = {name: '张三'}



    const c = deepClone(obj)
    console.log(c===obj);  // false