[面试整理]深拷贝和浅拷贝

90 阅读2分钟

浅拷贝

定义:

一般就是将对象的一层拷贝到新的对象上,深入的引用类型,他就是拷贝的内存地址。

实现

function shallowClone = (obj){
    const newObj = {}
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            newObj[key] = obj[key]
        }
    }
    return newObj
}

实例:

  1. concat()
  2. assign()
  3. 解构赋值

这些其实都是浅拷贝

let obj = {
    age: 18,
    nature: ['smart', 'good'],
    names: {
        name1: 'fx',
        name2: 'xka'
    },
    love: function () {
        console.log('fx is a great girl')
    }
}
var newObj = Object.assign({}, obj);
//console.log(newObj);
// 对数据进行更改
newObj.age = 22
newObj.names.name2 = 'summer'
console.log("obj",obj);
console.log("newObj", newObj);

浅拷贝.png

这边就可以看出,他只会修改一层,在后面的,他是直接拷贝的地址,所以newObj改的时候,obj也会改

浅拷贝只管一层,你的键里面的其他引用结构的值,他是不管的,他只是将内存地址拷给了要拷贝的那个

深拷贝

定义:

他一般就是递归的进行,如果对象里面的键还是对象,他还是会继续拷贝,完全替换掉每一个引用类型

实现

function deepClone(obj){
    let newObj = {}
    for(let key of obj){
        let value = obj[key]
        if(typeof value === "onject"){
            newObj[key]=deepClone(value)
        }else{
            newObj[key] = value
        }
    }
    return newObj
}

实例

// 一般深拷贝都需要一个递归实现,就是一直将引用类型变为基本类型为止
const deepClone = (obj) => {
    // 深拷贝结果
    let res = {}
    for (let key in obj) {
        let value = obj[key]
        // 判断是不是引用类型
        if (typeof value === "object") {
            res[key] =  deepClone(value)
        } else {
            res[key] = value
        }
    }
    return res
}

let deepCloneObj = deepClone(obj)
deepCloneObj.names.name1 = "summer"
deepCloneObj.age = 20
console.log("obj", obj);
console.log("deepCloneObj",deepCloneObj);

深拷贝.png

其实我们可以将深拷贝理解为,他们是完全独立的两个对象,相互之间不会产生任何影响

参考链接:

写给女朋友的中级前端面试秘籍(含详细答案,15k级别) - 掘金 (juejin.cn)

面试官:深拷贝浅拷贝的区别?如何实现一个深拷贝? | web前端面试 - 面试官系列 (vue3js.cn)