JavaScript中什么叫深拷贝?

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

深拷贝是一种常见的数据复制方式,它通常用于避免在操作对象时修改原始对象。在 JavaScript 中,可以使用多种方法进行深拷贝,包括递归遍历对象、lodashdeepClone 方法、使用 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:为可选参数,是一个可转移对象的数组,里面的 值 并没有被克隆,而是被转移到被拷贝对象上。

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

相关推荐
oliveira-time40 分钟前
Java 1.8(也称为Java 8)
java·开发语言
运维@小兵2 小时前
vue注册用户使用v-model实现数据双向绑定
javascript·vue.js·ecmascript
嗯.~4 小时前
【无标题】如何在sheel中运行Spark
前端·javascript·c#
钰爱&5 小时前
【Linux】POSIX 线程信号量与互斥锁▲
java·开发语言·jvm
yt948325 小时前
Matlab实现绘制任意自由曲线
开发语言·matlab
oioihoii7 小时前
C++23 std::generator:用于范围的同步协程生成器 (P2502R2, P2787R0)
开发语言·c++·c++23
免檒7 小时前
go基于redis+jwt进行用户认证和权限控制
开发语言·redis·golang
没有梦想的咸鱼185-1037-16637 小时前
全球森林数据如何分析?基于R语言森林生态系统结构、功能与稳定性分析与可视化
开发语言·随机森林·数据分析·r语言
Your易元7 小时前
设计模式-迭代器模式
java·开发语言
2401_858286117 小时前
CD37.【C++ Dev】string类的模拟实现(上)
开发语言·c++·算法