手写深拷贝和浅拷贝

145 阅读2分钟

引言

在上一篇文章中,我们聊到了深拷贝和浅拷贝,不知道的掘友们可以去看 (不知深浅的拷贝),在这篇文章中,我将带领大家手写深拷贝和浅拷贝!

浅拷贝

//浅拷贝的实现原理
let obj = {
    name:'www',
    age:18,
    like:{
        type: 'coding'
    }
}
let arr = [1,'a',null]
function shalldowCopy(obj){
    //类型判断
    if(typeof obj !== 'object' || obj == null) return 
    let objCopy = obj instanceof Array ? []:{}
        for(let key in obj){
            if(obj.hasOwnProperty(key)){
                objCopy[key] = obj[key] 
            }
        }
    return objCopy
}
let newObj = shalldowCopy(obj)
obj.like.type = 'sleeping'
console.log(newObj.like.type);//sleeping

我们这里实现的是数组和对象的浅拷贝

1 .我们可以在方法中看到在12行我们先判断了传进来的obj是否不为对象或者obj为null,这样我们就可以确保传入的obj为对象或者数组,如果有掘友对于类型判断仍心存疑虑,可以去看这篇文章"探秘JavaScript:类型判断的奇妙世界(一)"

2 .在判断完以后,我们用到了一个三目运算符,将objCopy 定义为传入的obj类型。

3 .在第14行,我们开始用 for in 方法遍历obj,for in 方法有一个缺点,就是可能会遍历到不属于obj的属性,所以我们在for in中进行判断,如果key为obj中的属性,则在objCopy中创建一个同样的属性并赋值。

4.在22行改变obj.like.type的值,在23行打印发现newobj.like.type也随之改变,我们的浅拷贝就写好了

深拷贝

//手动实现深拷贝
let obj = {
    name:'www',
    age:18,
    like:{
        type: 'coding'
    }
}
function deepCopy(obj){
    let objCopy = {}
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            if(obj[key] instanceof Object){
                objCopy[key] = deepCopy(objCopy[key])
            }else{
                objCopy[key] = obj[key]
            }
        }
    }
    return objCopy
}

这里的代码仅实现了对象的深拷贝,对于数组如何进行深拷贝,相信你看完这段代码就会有些思路了

前面的思路和浅拷贝一模一样,在第13行开始改变,我们来想想,浅拷贝和深拷贝的区别在哪里?因为在拷贝中向新数组传入了地址,导致浅拷贝,那么我们就要在新对象中避免传入地址。我们在第13行判断obj[key]是否为一个对象,如果为对象,那么我们运用递归再调用deepCopy,反之则直接复制。 最后我们返回的结果将不会再有原对象中的地址,那么一个简单的对象深拷贝就写完了。

结尾

在面试的时候,可能会被面试官要求手写浅拷贝和深拷贝,希望掘友们看完这篇文章能有所收获,从容面对开发和面试!