换工作遇到的面试题记录总结(深克隆浅克隆)

深克隆这个问题一般在考察js基础的时候问的频率还是比较大的.那么什么是深克隆什么是浅克隆呢,怎么实现一个深克隆呢?

1.简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。
2.对于简单数据类型来说他的值是直接存储在栈内存的,而对于引用数据来说,他在栈内存中只是存储了一个引用,真正的数据是存储在堆内存的.

首先 实现一个浅克隆的方法很简单

    //1.通过直接赋值
    let obj = { a:1,b:2,c:{d:1} }
    //如果我们想通过浅克隆 克隆这个对象
    let obj1 = obj
    console.log(obj1===obj)//true
    //2.通过es6的拓展运算符展开到新的对象内也是浅克隆
    let obj2 = {...obj}
    console.log(obj2===obj)//false 第一层地址被改变了
    //但是我们修改一下obj.c.d=2,我们会发现obj2.c.d也被修改了 第二层依旧是浅拷贝
复制代码

image.png
那么我们的项目需求是实现一个深拷贝,应该怎么做呢?

    //1.比较简单的一个方法就是通过JSON转化一下
    let obj3 = JSON.parse(JSON.stringify(obj))
复制代码

image.png

//确实实现了,对于不复杂的数据结构来说这个方法还是很简便的,但是如果我们对象的二级结构是一个函数,Date,正则呢
//让我们为obj添加新的属性
obj.date = new Date()
obj.reg = /^\d+$/
//通过JSON的方法之后发现Date别转化为了字符串,正则为空对象,这肯定不是我们想要的结果
复制代码

image.png

//这个时候我们就需要用js处理了
const deepClone = (obj)=>{
    //判断特殊情况
    if(obj===null) return null
    if(typeof obj !=='object') return obj
    if(obj instanceof RegExp) return new RegExp(obj)
    if(obj instanceof Date) return new Date(obj)
    //let newObj = new Object()
    //不直接创建一个新对象,保证克隆的结果和之前保持相同的所属类
    let newObj = new obj.constructor()
    for(key in obj){
        if(obj.hasOwnProperty(key)){
            newObj[key] =deepClone(obj[key])//使用递归进行深层赋值
        }
    }
    return newObj
}
let obj4 = deepClone(obj)


复制代码

image.png
这个时候就对复杂数据进行了深克隆

补充

es6的Object.assgin()属性实现的也是浅拷贝

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。也就是说,如果对象的属性值为简单类型(如string, number),通过Object.assign({},srcObj);得到的新对象为深拷贝;如果属性值为对象或其它引用类型,那对于这个对象而言其实是浅拷贝的。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享