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:为可选参数,是一个可转移对象的数组,里面的 值 并没有被克隆,而是被转移到被拷贝对象上。

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

相关推荐
To_OC14 小时前
写了三遍 Todo List,我终于搞懂了 React 父子组件到底怎么通信
前端·javascript·react.js
勇往直前plus15 小时前
Vue3(篇一) 核心概念——响应式模板语法与组件基础
前端·javascript·vue.js
用户9385156350716 小时前
从零搭建 AI 日记助手:用 Milvus 向量数据库 + RAG 让机器读懂你的每一天
javascript·人工智能·全栈
互联网中的一颗神经元16 小时前
小白python入门 - 39. 采集流水线小项目
开发语言·python
Wang's Blog17 小时前
Go-Zero 项目开发22:用户群聊功能的实现与完善
开发语言·golang
a11177617 小时前
坦克大战3D Three.js 3D (开源项目)
开发语言·javascript·3d
kyriewen18 小时前
别再乱用useEffect了——你写的10个里有8个不该存在
前端·javascript·react.js
Ivanqhz18 小时前
Rust &‘static str浅析
java·前端·javascript·rust
Wang's Blog19 小时前
Go-Zero项目开发24: 基于Bitmap实现群聊消息已读未读
开发语言·后端·golang
zandy101119 小时前
衡石 Agentic BI的ReAct 推理框架在 Agentic BI 中的工程化实践
前端·javascript·react.js