JavaScript中什么叫深拷贝?

在 JavaScript 中,深拷贝指的是创建一个新的对象,这个新的对象与原始对象完全独立,没有任何共享的属性或者数据,它们不共享同一块内存地址。深拷贝会复制原始对象的所有属性和嵌套对象的所有属性,包括嵌套对象中的属性。这意味着,修改拷贝后的对象不会影响原始对象。

深拷贝是一种常见的数据复制方式,它通常用于避免在操作对象时修改原始对象。在 JavaScript 中,可以使用多种方法进行深拷贝,包括递归遍历对象、lodash 的 deepClone 方法、使用 JSON 序列化和反序列化等方式。

JSON 序列化

利用 JSON 序列化和反序列化实现深拷贝,具体实现步骤如下:

  1. 使用 JSON.stringify() 方法将原始对象序列化为 JSON 字符串。

  2. 使用 JSON.parse() 方法将 JSON 字符串反序列化为新对象。

    function deepClone(obj) {
    return JSON.parse(JSON.stringify(obj));
    }

    const profile = {
    name: "天行无忌",
    city: "深圳",
    };
    const newProfile = deepClone(profile);
    newProfile.city = "广东深圳";
    console.log(profile); // { name: '天行无忌', city: '深圳' }
    console.log(newProfile); // { name: '天行无忌', city: '广东深圳' }

使用 JSON 序列化和反序列化实现深拷贝存在一些局限性

  • 无法复制函数、正则表达式等特殊对象类型。
  • 无法复制对象的循环引用,即对象中存在自己或父对象的引用。

递归遍历对象

以下是一个使用递归遍历实现深拷贝的代码:

复制代码
function deepClone(obj) {
    if (obj === null || typeof obj !== "object") {
        return obj;
    }

    let result = obj.constructor();

    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            result[key] = deepClone(obj[key]);
        }
    }

    return result;
}

const profile = {
    name: "天行无忌",
    city: "深圳",
};
const newProfile = deepClone(profile);
newProfile.city = "广东深圳";
console.log(profile); // { name: '天行无忌', city: '深圳' }
console.log(newProfile); // { name: '天行无忌', city: '广东深圳' }

使用 structuredClone

原生 structuredClone() 方法使用结构化克隆算法创建给定值的深层拷贝。

结构化克隆算法用于复制复杂 JavaScript 对象的算法。通过来自 Worker 的 postMessage() 或使用 IndexedDB 存储对象时在内部使用。它通过递归输入对象来构建克隆,同时保持先前访问过的引用的映射,以避免无限遍历循环。

语法如下:

复制代码
structuredClone(value)
structuredClone(value, { transfer })
  • value:被克隆的对象。可以是任何结构化克隆支持的类型。
  • transfer:为可选参数,是一个可转移对象的数组,里面的 值 并没有被克隆,而是被转移到被拷贝对象上。

返回值:返回值是原始值的深拷贝。

相关推荐
不会算法的笨小孩8 分钟前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常
Penge66628 分钟前
《Go 后端开发者学 TypeScript:typescript 类型断言》
javascript
Penge66632 分钟前
《Go 后端开发者学 TypeScript:Symbol》
javascript
Hhy_11072 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
starzy19902 小时前
深入理解Scala函数定义:从方法到函数的类型跨越
开发语言·scala
starzy19903 小时前
深入理解Scala递归函数:从栈溢出到尾调用优化
开发语言·scala
三*一3 小时前
Mapbox‑GL JS 多边形折点编辑工具:实现原理、功能拆解与踩坑总结
开发语言·javascript·ecmascript
YSL0701243 小时前
C++基础
开发语言·c++
若亦_3 小时前
Java中关于this的三种用法
java·开发语言·intellij-idea
2601_968793143 小时前
Python Requests 轻量自动化:无需浏览器,实现真人级账号浏览模拟
开发语言·python·自动化