百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

浅拷贝与深拷贝全面解析及实战(浅拷贝和深拷贝的实现方式)

wptr33 2025-03-20 20:08 17 浏览

在JavaScript学习中,拷贝是很重要的一个知识点。拷贝主要分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。本文将阐述两者的概念,还将通过手写示例深入探讨如何实现这两种拷贝方式,以及它们在实际应用中的考量。

浅拷贝:表面级复制

浅拷贝只复制对象的第一层属性,对于嵌套对象或数组,仅复制它们的引用,导致原对象和拷贝对象在这些部分仍然共享数据。

实现方法:

let obj = {
    a: 1, 
    b: [1,2,3]
}
  • Object.create(obj) let obj2 = Object.create(obj);
  • Object.assign({}, obj) let obj2 = Object.assign({}, obj);
  • Array.concat()
  • const arr = [1, 2, 3];
    const newArr = [].concat(arr);
    console.log(newArry); // 输出 [1, 2, 3]
    • Array.slice(0)
        const arr = [1, 2, 3];
        const newArr = original.slice(0);
        console.log(newArr); // 输出 [1, 2, 3]
    • Array.toReverse().reverse()
        const arr = [1, 2, 3];
        const newArr = arr.toReversed().reverse();
        console.log(newArr); // 输出 [1, 2, 3]
    • 扩展运算符 ...args
        const arr = [1, 2];
        const newArr = [...arr];
        console.log(newArr); 

    手写浅拷贝示例

    • 实现原理:forin循环遍历对象中的所有属性借助hasOwnProperty()方法,判断属性是否为对象显式属性
    • 实现代码:
    function shallowCopy(obj) {
        let newObj = Array.isArray(obj) ? [] : {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                newObj[key] = obj[key];
            }
        }
        return newObj;
    }

    特点

    • 执行速度快,占用资源少。
    • 适用于简单对象或不需要完全独立拷贝的场景。
    • 不适用于包含嵌套对象或数组的复杂结构,因为更改嵌套数据会影响原对象。

    深拷贝:彻底复制

    深拷贝会递归地复制对象的所有层次,包括嵌套的数组和对象,从而确保原对象和拷贝对象完全独立,互不影响。

    实现方法:

    • JSON.parse(JSON.stringify(obj))(有局限性)
         const original = { a: 1, b: { c: 2 } };
         const copy = JSON.parse(JSON.stringify(original));
         console.log(copy); // 输出 { a: 1, b: { c: 2 } }
    • structuredClone(obj)(较新,但仍有限制)
        const original = { a: 1, b: { c: 2 } };
        const copy = structuredClone(original);
        console.log(copy); // 输出 { a: 1, b: { c: 2 } }
    • 自定义递归函数实现

    手写深拷贝示例

    • 实现原理:
    1. forin循环遍历对象中的所有属性
    2. 借助hasOwnProperty()方法,判断属性是否为对象显式属性
    3. 判断属性值类型,递归调用深拷贝函数
    • 实现代码:
    function deepCopy(obj) {
        if (!obj || typeof obj !== 'object') {
            return obj;
        }
        let newObj = Array.isArray(obj) ? [] : {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                newObj[key] = deepCopy(obj[key]);
            }
        }
        return newObj;
    }


    特点

    • 创建完全独立的副本,适用于复杂数据结构。
    • 相对耗时和占用更多资源,尤其是面对深度嵌套对象。

    实践比较与选择

    • 性能与资源:浅拷贝因为操作简单,执行效率高,适合快速复制;深拷贝则因递归复制所有层级,成本较高,但在需要完全独立数据副本时不可或缺。
    • 应用场景:对于简单的对象复制或状态克隆,浅拷贝足矣;而在需要确保数据完全隔离,避免外部修改影响内部状态时,深拷贝是更好的选择。
    • 注意事项:使用JSON.stringify()和JSON.parse()进行深拷贝虽简便,但存在局限性(如不支持函数、Symbol、循环引用等)。自定义深拷贝时,循环引用的处理是一个常见的挑战。

    结论

    浅拷贝和深拷贝各有千秋,关键在于根据具体需求选择合适的拷贝策略。了解它们的实现机制,不仅能提升代码的健壮性,还能有效避免潜在的数据篡改问题。通过手写实现深浅拷贝,不仅可以加深对JavaScript对象的理解,也能在特定场景下提供灵活的解决方案。


    文章转自:
    https://juejin.cn/post/7379151898567622696

    相关推荐

    台积电提出SRAM存内计算新方法,能效比可达89TOPS/W

    芯东西(公众号:aichip001)编译|高歌编辑|云鹏芯东西3月16日消息,近期,台积电的研究人员在ISSCC2021会议上公布了一种改良的SRAM存储器阵列,该SRAM阵列采用22nm工...

    Golang中如何判断两个slice是否相等?

    在Golang中,要判断两个slice是否相等是不能直接使用==运算符的(==只能说明两个slice是否指向同一个底层数组)。如果两个slice的底层数组相同,但长度或容量不同...

    JS入门基础知识(js基础知识总结笔记)

    JS对象操作对象增删改查创建对象letobj={}新增属性obj.a=1修改属性obj.a='a'...

    趣谈JS二进制:File、Blob、FileReader、ArrayBuffer、Base64

    大家好,我是Echa。好久没跟粉丝们细聊JavaScript那点事了。做一名全栈工程师,JS基础还是要打牢,这样的话不管底层业务逻辑以及第三方框架怎么变化,都离不开基础。本文文章属于基础篇,阅读有点...

    告别 substr() 和 substring()?更可靠的 JavaScript 字符串截取方法

    JavaScript提供了三个主要的字符串截取方法:...

    golang第九天,切片(slice)介绍(golang 切片作为参数)

    什么是切片golang切片是对数组的抽象。go的数组长度不可改变,在特定场景中这样的集合就不太适用,go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追...

    Go语言零到一:数组(go struct数组)

    引言...

    你说你熟悉Slice,这道slice题你能答对吗?

    每当你花费大量时间使用某种特定工具时,深入了解它并了解如何高效地使用它是很值得的。...

    Python 3.14七大新特性总结:从t-string模板到GIL并发优化

    Python3.14已进入测试阶段,根据PEP745发布计划,该版本已停止引入新功能,也就是说新特征就应该已经固定下来了。所以本文基于当前最新的beta2版本,深入分析了Python3.14中...

    Python 幕后:Python导入import的工作原理

    更多互联网精彩资讯、工作效率提升关注【飞鱼在浪屿】(日更新)Python最容易被误解的方面其中之一是import。...

    Python元类实现自动化编程的正确姿势

    元类是Python中用于创建类的类。通过元类机制,开发者可在运行时动态创建和修改类,为框架开发、设计模式实现和高级架构设计提供核心支持。在Python语言的高级特性中,元类占据着独特而重要的地位。作...

    Python字符串详解与示例(python字符串类型及操作)

    艾瑞巴蒂字符串的干货来了,字符串是程序中最常见的数据类型之一,用来表示数据文本,下面就来介绍下字符串的特性,操作和方法,和一些示例来吧道友:1.字符串的创建在python中字符串可以永单引号(...

    恕我直言!你对Python里的import一无所知

    文章来源:https://mp.weixin.qq.com/s/4WAOU_Lzy651IE-2zZSFfQ原文作者:写代码的明哥...

    Python基础:字符串操作(python字符串的用法)

    字符串是Python中最常用的数据类型之一,用于表示文本数据。我们将学习如何对字符串进行常见的操作,包括创建、访问、修改和处理字符串。通过掌握这些技巧,您将能够更好地处理和操作文本数据。让我们开始吧!...

    Python 中 字符串处理的高效方法,不允许你还不知道

    以下是Python中字符串处理的高效方法...