如何手写一个深拷贝?

深拷贝是面试的一个重要考点,要理解实现一个深拷贝的过程,下面将分析实现一个对象深拷贝的过程。

基本环境

  • 首先要保证电脑已经安装node.js,可通过终端node -v查看版本,对版本不作要求,具体安装过程可搜索相关博客。
  • npm是node的一个包管理工具,使用npm install http-server -g命令安装一个简单的静态服务器,使得网页能够在服务器上运行起来,相关命令是http-server -p 端口号

实现过程

  1. 封装一个深拷贝函数,调用此函数即可进行拷贝
  2. 对传入的参数进行判断,如果是null或不是对象或数组,直接返回,不进行深拷贝。
// 深拷贝函数
function deepClone(obj={}) {
    if(typeof obj !== 'object' || obj == null){
        // obj 是null,或者不是对象和数组,直接返回
        return obj
    }
    
}
复制代码
  1. 初始化返回结果,判断传入的参数是数组还是对象,如果是数组返回一个空数组,否则返回一个空对象
// 深拷贝函数
function deepClone(obj={}) {
    if(typeof obj !== 'object' || obj == null){
        // obj 是null,或者不是对象和数组,直接返回
        return obj
    }

    //初始化返回结果
    let result
    if(obj instanceof Array){
        result=[]
    }else{
        result={}
    }

    // 返回结果
    return result
    
}
复制代码
  1. 使用循环遍历数组或对象的每一项,判断每一项,使用obj.hasOwnProperty(key)保证 key不是原型链属性,然后对每一项进行递归,判断每一项类型,根据不同类型返回不同结果,追加至result里面,最后返回result即拷贝成功。
// 深拷贝函数
function deepClone(obj={}) {
    if(typeof obj !== 'object' || obj == null){
        // obj 是null,或者不是对象和数组,直接返回
        return obj
    }

    //初始化返回结果
    let result
    if(obj instanceof Array){
        result=[]
    }else{
        result={}
    }

    for(let key in obj){
    // 保证 key 不是原型的属性
        if(obj.hasOwnProperty(key)){
            // 递归调用
            result[key]=deepClone(obj[key])
        }
    }

    // 返回结果
    return result
    
}
复制代码

使用以上封装的函数,实现一个深拷贝的例子

const obj1={
    age:20,
    name:'xxx',
    address:{
        city:'beijing'
    },
    arr:['a','b','c','d']
}

const obj2=deepClone(obj1)
obj2.address.city='shanghai'
console.log(obj1.address.city); // beijing

// 深拷贝函数
function deepClone(obj={}) {
    if(typeof obj !== 'object' || obj == null){
        // obj 是null,或者不是对象和数组,直接返回
        return obj
    }

    //初始化返回结果
    let result
    if(obj instanceof Array){
        result=[]
    }else{
        result={}
    }

    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            // 递归调用
            result[key]=deepClone(obj[key])
        }
    }

    // 返回结果
    return result
    
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享