js中浅拷贝,深拷贝的实现

56 阅读2分钟

在JavaScript中,浅拷贝和深拷贝是两种复制对象的方式,它们的主要区别在于是否复制对象的引用类型属性

  1. 浅拷贝:浅拷贝只复制对象的基本类型的属性,如果属性是引用类型(如数组、对象),则复制的是引用,而不是实际的对象。这意味着如果你修改了复制后的对象的引用类型属性,原对象的对应属性也会被修改。

  2. 深拷贝:深拷贝不仅复制对象的基本类型的属性,还会复制引用类型的属性。这意味着它会创建一个新的对象,并复制原对象的所有属性和嵌套的属性。因此,修改复制后的对象的任何属性,都不会影响到原对象。

浅拷贝的实现


// 接收传进来的参数 可能是数组 或者是对象
function clone(obj) {
    // 进行obj 参数类型的判断
    // 如果 object ==> {} array ==>[]
    const newObj = Array.isArray(obj) ? [] : {}
    // 遍历老对象 或者 老数组 
    for (const key in obj) {
        // 进行赋值操作
        // key  属性名
        newObj[key] = obj[key]
        // 但是这里有一个问题, 比如说 引用数据类型 对象啊 数组啊, 你这样赋值的话,相当于
        // 直接把地址拷贝过来了, 修改新对象里面的引用数据类型的属性的时候,也会影响到了源对象
        // 类似
        // newfruit[name] = fruit[name]
    }

    return newObj

}

深拷贝的实现

深拷贝的主要实现步骤相较于浅拷贝 主要在于 对于原对象引用数据类型的属性值的处理

主要使用的是函数递归的方法 一层一层的走下去


/**
 * 深拷贝的思路:
 * 1. 对进行被拷贝对象数据类型的判断 数组 || 对象
 * 2. 如果是数组 就创建一个空数组 ; 如果是对象 就创建一个空对象 (主要为了开辟新的内存空间)
 * 3. 遍历数组 或者 对象 (depend on 原对象的类型)
 * 4. 原对象身上的基础数据类型直接赋值即可. 如果是引用数据类型,进行递归函数调用  
 * 5. 返回新创建的数组 或者 对象
 *
 */
 
// 接收传进来的参数 可能是数组 或者是对象
function deepClone(obj) {
    // 进行obj 参数类型的判断
    // 如果 object ==> {} array ==>[]
    const newObj = Array.isArray(obj) ? [] : {}
    // 遍历老对象 或者 老数组 
    for (const key in obj) {
        // 如果是引用数据类型的话
        if (typeof newObj[key] == "object") {
            newObj[key] = deepClone(obj[key])
        }
        // 基础数据类型 直接进行赋值操作
        // key  属性名
        newObj[key] = obj[key]
        // 但是这里有一个问题, 比如说 引用数据类型 对象啊 数组啊, 你这样赋值的话,相当于
        // 直接把地址拷贝过来了, 修改新对象里面的引用数据类型的属性的时候,也会影响到了源对象
        // 类似
        // newfruit[name] = fruit[name]
    }
    return newObj
}