带你详细刨析JavaScript 对象数组的深浅拷贝

发布时间 2023-07-27 11:39:03作者: 可爱的小锋

深浅拷贝

●深浅拷贝指的是一种复制对象或者数组的行为
●也就是把一个对象或者数组中的数据完完整整的复制一份放到另一个数组或者对象中
●并且相互之间没有联系
●说道深浅拷贝这个我们不考虑基本数据类型
●因为基本数据类型没有引用地址一说
●说到复制这个事儿 有三个级别
○赋值
○浅拷贝
○深拷贝

赋值
●就是把一个变量存储的内容复制一份给另一个变量
●基本数据类型赋值以后两个变量之间没有关系
●修改任何一个的值都不会影响另一个
●复杂数据类型赋值以后,两个变量操作一个空间
●修改一个的值另一个也会跟着改变

// 赋值
// 基本数据类型
let num = 100
let num1 = num
console.log(num, num1);
num1 = 200
console.log(num, num1);
// 复杂数据类型
let o1 = { name: 'Jack', age: 25 }
let o2 = o1
console.log(o1, o2);
o2.name = 'Rose'
console.log(o1, o2);

浅拷贝

●说到浅拷贝就不考虑基本数据类型了
●就是按照原先的数据类型创建一个新的一样的数据类型
●把原始数据中的每一个数据依次赋值到新的数据类型中
●通过分析我们发现浅拷贝只能拷贝一层
●并且是简单数据类型 如果有第二层甚至多层就不能实现完完整整的复制

// 浅拷贝
// 准备原始数据
const o1 = {
    name: 'Jack',
    age: 25,
    color: {
        red: '红色',
        blue: '蓝色'
    }
}
// 实现拷贝
// 首先创建一个新的数据
const o2 = {}
// 遍历循环原始数据类型
for (let k in o1) {
    // 接下来就是把原始数据类型中的数据赋值到新创建的数据类型中
    // 如果这个时候元素对象中还复杂数据类型
    // 同样是赋值 依然不能实现完完整整的复制
    o2[k] = o1[k]
}
console.log(o1, o2);
// 修改o1中的值
o1.color.red = '红颜色'
console.log(o1, o2);

深拷贝

●就是要百分百的拷贝一份原始数据
●修改任何里面的数据都不会影响另一个里面的数据
●不管层级有多深 都能完整的复制过来 两个之间没有关系
●这就要通过深拷贝
●深拷贝的核心:递归

// 准备数据
const o1 = {
    name: 'Jack',
    age: 18,
    info: {
        height: 180,
        weight: 180,
        desc: {
            message: '今天天气很好'
        }
    },
    address: {
        city: '北京'
    },
    hobby: ['吃饭', '睡觉']
}
// 准备一个空对象
const o2 = {}
// 要实现深拷贝 我们就准备一个函数
function deepCopy(o2, o1) {
    // 首先我们还是要通过循环遍历的方式拿到原始数据类型中的数据
    for (let k in o1) {
        // 因为我们不知道里面都有什么数据所以我们要先判断
        if (Object.prototype.toString.call(o1[k]) === '[object Object]') {
            // 代码能进入到这里说明是一个对象
            o2[k] = {}
            // 再次进行拷贝 这个过程和我们刚做的是不是一样
            // 那我就直接调用我们的deepCopy函数就好
            deepCopy(o2[k], o1[k])
        } else if (Object.prototype.toString.call(o1[k]) === '[object Array]') {
            // 代码能执行到这里说明是一个数组
            o2[k] = []
            // 继续执行我们的拷贝函数
            deepCopy(o2[k], o1[k])
        } else {
            o2[k] = o1[k]
        }
    }
}
// 使用
deepCopy(o2, o1)
console.log(o1, o2);
o1.info.height = 300
console.log(o1, o2);