当前位置: 首页 > article >正文

javaScript中的浅拷贝和深拷贝详解

在 JavaScript 中,浅拷贝深拷贝 的主要区别在于它们如何处理对象中的嵌套对象(即对象的属性也是对象的情况)。

1. 浅拷贝

浅拷贝只复制对象的第一层属性。如果对象的属性是一个引用类型(如对象或数组),浅拷贝只会复制该引用的地址,而不是实际的值。这意味着,如果你修改了拷贝对象中引用类型的属性,原对象中的该属性也会被修改。

常见的浅拷贝方式:
  • Object.assign()
  • 扩展运算符 ...
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = Object.assign({}, obj1);
// 或者
let obj3 = { ...obj1 };

// 修改 obj2 中的 b 属性
obj2.b.c = 3;

console.log(obj1.b.c); // 输出 3,因为 obj1 和 obj2 共享同一个 b 对象的引用

2. 深拷贝

深拷贝会递归地复制对象的所有层次,包括嵌套的对象和数组。这意味着拷贝后的对象和原对象完全独立,修改拷贝对象的任意部分都不会影响原对象。

实现深拷贝的常见方法:
1. 使用 JSON.stringify()JSON.parse()

这是一种简单但不太灵活的方法,它会将对象序列化为 JSON 字符串,再解析为新对象。它有一些局限性,比如不能处理 undefined、函数、循环引用等复杂数据结构。

let obj1 = { a: 1, b: { c: 2 } };
let obj2 = JSON.parse(JSON.stringify(obj1));

// 修改 obj2 中的 b 属性
obj2.b.c = 3;

console.log(obj1.b.c); // 输出 2,因为 obj1 和 obj2 是完全独立的
2. 递归实现深拷贝:

为了实现更健壮的深拷贝,可以手动递归地复制对象的每一层属性。

function deepClone(obj) {
    // 如果不是对象或者是 null,直接返回原值
    if (typeof obj !== "object" || obj === null) {
        return 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: 1, b: { c: 2 } };
let obj2 = deepClone(obj1);

obj2.b.c = 3;

console.log(obj1.b.c); // 输出 2,拷贝是深层的
3. 使用 Lodash 库的 cloneDeep 方法:

Lodash 是一个流行的 JavaScript 工具库,它提供了一个强大的深拷贝方法 _.cloneDeep(),可以处理复杂的数据结构。

let _ = require('lodash'); // 引入 lodash 库
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = _.cloneDeep(obj1);

obj2.b.c = 3;

console.log(obj1.b.c); // 输出 2

深拷贝和浅拷贝的应用场景:

  • 浅拷贝 适合简单的、没有嵌套对象的数据结构。
  • 深拷贝 在处理包含复杂对象、嵌套对象或数组时更为合适,因为这确保了数据的独立性。

总结:

  • 浅拷贝:只复制第一层的属性,嵌套对象引用仍然指向原来的对象。
  • 深拷贝:递归复制所有层次的属性,拷贝后的对象与原对象完全独立。

http://www.kler.cn/news/329967.html

相关文章:

  • synchronized底层是怎么通过monitor进行加锁的?
  • 【Bug】解决 Ubuntu 中 “error: Unable to Find Python3 Executable” 错误
  • 【C++算法】4.双指针_快乐数
  • redis 中IO多路复用与Epoll函数
  • 结合了LLM(大语言模型)的编辑器,不仅能理解人类语言,还能与用户互动,仿佛有了自己的思想。...
  • [倍福PLC]TwinCAT标准数据类型
  • WIFI网速不够是不是光猫的“路由模式”和“桥接模式”配置错了?
  • 在CentOS 7上安装WordPress的方法
  • 深入理解 C 语言中的内存操作函数:memcpy、memmove、memset 和 memcmp
  • Leetcode 每日一题:Crack The Safe
  • OSINT技术情报精选·2024年9月第4周
  • 经典面试题目---Spring IOC容器的核心实现原理
  • 数字控制系统
  • 区块链技术简介
  • 利用QGIS将.shp文件转换成json文件
  • VR 尺寸美学主观评价-解决方案-现场体验研讨会报名
  • 简单实现log记录保存到文本和数据库
  • 【Ubuntu】apt安装时报错:不再含有 Release 文件
  • ab plc1756连接Profinet 转 EtherNet/IP 网关进行数据交互
  • 面试速通宝典——7