JavaScript深拷贝与浅拷贝实现详解

作者:拾光

时间:2026-10-25

浏览:539

本文详解JavaScript中深拷贝与浅拷贝的区别及实现方式。通过对比基本类型与引用类型的内存分配,解析解构赋值的拷贝特性。介绍简单版、够用版递归深拷贝代码的局限性,并推荐原生structuredClone方法及第三方库在实际开发中的应用。

文章目录

针对基本类型数据

其赋值操作均视为深拷贝。

针对引用类型数据

针对引用类型数据,浅拷贝操作仅复制引用地址,致使两个对象共享同一引用地址并指向相同的内存空间及数据值。此时对任一对象执行操作,均会修改该引用地址所指向的数据值。

执行深拷贝时,会在堆内存中开辟全新区域存放对象副本,确保修改新对象不会波及原对象。

解构赋值属于深拷贝还是浅拷贝?

若数组为一维结构,可视为深拷贝。

        let arr = [1, 2, 3]
        let copyArr = [...arr]
        copyArr.push(4)
        console.log(arr, copyArr) 

针对基本类型数据

若数组为多维嵌套结构,则属于浅拷贝。

        let arr2 = [[1, 2, 3], [9, 0, 6]]
        let copyArr2 = [...arr2]
        copyArr2[0].push(77)
        console.log(arr2, copyArr2)

针对基本类型数据

注意:简单赋值仅复制引用地址:

const a1 = [1, 2];
const a1Copy = a1;
a1Copy[0] = 9;
console.log(a1)  // [9, 2]
console.log(a1Copy) // [9, 2]

若不使用扩展运算符,ES5中可采用替代方法实现数组拷贝。

const a1 = [1, 2];
const a1Copy = a1.concat();
a1Copy[0] = 9;
a1 // [1, 2]

实现深拷贝

简单版

在不依赖第三方库的前提下,尝试对对象进行深拷贝。

const newObj = JSON.parse(JSON.stringify(oldObj))

局限性:

  • 无法处理RegExp、Date、Set、Map等特殊对象的克隆。
  • 无法拷贝函数。
  • 会丢失对象的constructor,所有构造函数指向Object。
  • 若对象存在循环引用,将导致报错。

够用版

利用递归逻辑实现数组或对象的拷贝。

function deepClone(source) {
    // 定义结果对象或数组
    const targetObj = source.constructor === Array ? [] : {}
    // 遍历key
    for (let keys in source) {
        // 如果key是对象的自有属性
        // hasOwnProperty()查找一个对象是否有某个属性,但是不会去查找它的原型链。
        if (source.hasOwnProperty(keys)) {
            // 如果是引用类型
            if (source[keys] && typeof source[keys] === 'object') {
                // 递归
                targetObj[keys] = deepClone(source[keys])
            } else {
                // 如果是基本类型
                targetObj[keys] = source[keys]
            }
        }
    }
    return targetObj
}
  • 关于解决循环引用、拷贝特殊对象及函数等复杂情况,因不常见,本文未提供相关代码。
  • 在实际开发中,建议使用第三方库进行数据克隆。

新发现一种原生深拷贝方法,

structuredClone

全局的structuredClone()方法利用结构化克隆算法对给定值进行深拷贝。

适用于H5环境;

Error以及Function对象无法被结构化克隆算法复制,存在上述缺点。

详情可查阅MDN:传送门

let obj = {
  a: [1, 2],
  b: "eee",
  c: 3,
};
let cloneObj = structuredClone(obj);
cloneObj.a[0] = 10;
console.log(cloneObj.a[0]); // 10
console.log(obj.a[0]);      // 1

至此,关于JavaScript深拷贝与浅拷贝实现详解的介绍结束,更多相关JS深拷贝与浅拷贝内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章