深入探讨JavaScript中的对象拷贝

一、浅拷贝

浅拷贝是指在JS中对象之间的引用关系,即拷贝源对象的引用,而不是源对象的副本。在浅拷贝中,源对象和目标对象会引用同一个内存地址中的内容,因此当源对象中的某个属性值发生改变时,目标对象中的相应属性值也会随之改变。

// 浅拷贝示例
let obj1 = { a: 10, b: { c: 20 } };
let obj2 = Object.assign({}, obj1);
obj1.b.c = 30;
console.log(obj2.b.c); // 30

如上述代码所示,当我们改变源对象obj1中的b.c属性值时,因为obj2是浅拷贝得到的,所以其相应属性值也被改变了。

然而,如果数值、字符串等基本数据类型的属性值发生改变,浅拷贝则不会发生变化,因为基本数据类型的值是存储在栈内存中的实际值,深浅拷贝都是拷贝了这个值。

二、深拷贝

深拷贝是指完全复制一个对象或多个嵌套对象的值,并将其复制到新的内存地址中。也就是说,源对象和目标对象是完全独立的,互不关联,互相之间的修改不会互相影响。

// 深拷贝示例
function deepClone(obj) {
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }
    // 根据obj的类型创建一个新的对象
    let newObj = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
        // 判断一个对象是否是自己的属性
        if (obj.hasOwnProperty(key)) {
            // 递归调用复制函数
            newObj[key] = deepClone(obj[key]);
        }
    }
    return newObj;
}
let obj1 = { a: 10, b: { c: 20 } };
let obj2 = deepClone(obj1);
obj1.b.c = 30;
console.log(obj2.b.c); // 20

如上述代码所示,当我们改变源对象obj1中的b.c属性值时,目标对象obj2不会受到影响,因为它们是完全独立的。

三、序列化和反序列化

JavaScript中的对象可以通过JSON.stringify()方法序列化为JSON格式的字符串,然后再通过JSON.parse()方法反序列化为新的对象。

// 序列化和反序列化示例
let obj1 = { a: 10, b: { c: 20 } };
let str = JSON.stringify(obj1);
let obj2 = JSON.parse(str);
obj1.b.c = 30;
console.log(obj2.b.c); // 20

如上述代码所示,在将序列化后的JSON字符串反序列化为新的对象后,它们是完全独立的,相互之间不会产生影响。但是这种方法也有其缺点,因为在序列化和反序列化过程中,一些特殊的对象和属性,如Date、RegExp、Function等,在序列化时无法得到正确的表现,因此可能会导致一些不可预测的结果。

四、使用第三方库

除了上述三种方法外,还可以使用一些优秀的第三方库提供的对象拷贝方法,如jQuery的$.extend()方法、lodash的_.cloneDeep()方法等,这些方法都针对不同的应用场景提供了完善的解决方案。

// underscore.js/lodash类库提供深拷贝方法_.cloneDeep()的使用示例
let obj1 = { a: 10, b: { c: 20 } };
let obj2 = _.cloneDeep(obj1);
obj1.b.c = 30;
console.log(obj2.b.c); // 20

五、结语

JavaScript对象拷贝并不是一个简单的问题,根据应用场景的不同,选择不同的拷贝方式才能得到预期的结果。开发者需要多加注意,灵活选用不同的拷贝方法以满足应用需求。

原创文章,作者:NCWUL,如若转载,请注明出处:https://www.506064.com/n/362681.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
NCWULNCWUL
上一篇 2025-02-27 19:28
下一篇 2025-02-27 19:28

相关推荐

  • 面向对象编程、类和对象

    面向对象编程(Object-Oriented Programming, OOP)是一种编程方法,它将现实世界中的事物抽象为对象(Object),对象的属性和方法被封装成类(Clas…

    编程 2025-04-29
  • Mapster:一个高性能的对象映射库

    本文将深入介绍furion.extras.objectmapper.mapster,一个高性能的对象映射库,解释它是如何工作的以及如何在你的项目中使用它。 一、轻松地实现对象之间的…

    编程 2025-04-28
  • 使用JavaScript日期函数掌握时间

    在本文中,我们将深入探讨JavaScript日期函数,并且从多个视角介绍其应用方法和重要性。 一、日期的基本表示与获取 在JavaScript中,使用Date对象来表示日期和时间,…

    编程 2025-04-28
  • Python返回对象类型

    Python是一种动态、解释型、高级编程语言。Python是一种面向对象的语言,即所有的一切都是一个对象。 一、基本类型 Python中的基本类型有整数int、浮点数float、布…

    编程 2025-04-28
  • JavaScript中使用new Date转换为YYYYMMDD格式

    在JavaScript中,我们通常会使用Date对象来表示日期和时间。当我们需要在网站上显示日期时,很多情况下需要将Date对象转换成YYYYMMDD格式的字符串。下面我们来详细了…

    编程 2025-04-27
  • Python中通过对象不能调用类方法和静态方法的解析

    当我们在使用Python编写程序时,可能会遇到通过对象调用类方法和静态方法失败的问题,那么这是为什么呢?接下来,我们将从多个方面对这个问题进行详细解析。 一、类方法和静态方法的定义…

    编程 2025-04-27
  • Python内置函数——查看对象内存

    本文将介绍Python内置函数中,在开发中查看对象内存的相关函数。 一、id()函数 id()函数是Python内置函数,用于返回对象的唯一标识符,也就是对象在内存中的地址。 nu…

    编程 2025-04-27
  • 解决ERP运行时错误429:ActiveX不能创建对象 DAO350

    ERP运行时错误429是由于“ActiveX不能创建对象”而引发的。这种错误通常是由于您在尝试访问Microsoft Access数据库时缺少了必要的组件。 一、安装并注册DAO库…

    编程 2025-04-27
  • JavaScript中修改style属性的方法和技巧

    一、基本概念和方法 style属性是JavaScript中一个非常重要的属性,它可以用来控制HTML元素的样式,包括颜色、大小、字体等等。这里介绍一些常用的方法: 1、通过Java…

    编程 2025-04-25
  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25

发表回复

登录后才能评论