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

使用JavaScript实现深浅拷贝

1. 拷贝的基本概念和必要性

在 JavaScript 中,数据类型分为基本数据类型(如 NumberStringBooleanNullUndefinedSymbol)和引用数据类型(如 ObjectArray)。基本数据类型存储的是值本身,而引用数据类型存储的是内存地址。当需要对数据进行操作且不想影响原始数据时,就需要进行拷贝。

2. 浅拷贝(Shallow Copy)

概念

浅拷贝创建一个新对象,新对象的顶层属性是原始对象属性的副本,但如果原始对象的属性是引用类型,新对象和原始对象会共享这些引用类型属性的内存地址。也就是说,修改新对象中引用类型的属性会影响原始对象中对应的属性。

实现方式
  • 扩展运算符(Spread Operator):常用于数组和对象的浅拷贝。
// 数组浅拷贝
const originalArray = [1, [2, 3]];
const shallowCopiedArray = [...originalArray];
shallowCopiedArray[1][0] = 9;
console.log(originalArray); // 输出: [1, [9, 3]]

// 对象浅拷贝
const originalObject = { a: 1, b: { c: 2 } };
const shallowCopiedObject = { ...originalObject };
shallowCopiedObject.b.c = 9;
console.log(originalObject.b.c); // 输出: 9
  • Object.assign():用于将一个或多个源对象的所有可枚举属性复制到目标对象。
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
shallowCopy.b.c = 9;
console.log(original.b.c); // 输出: 9
  • Array.prototype.slice():常用于数组的浅拷贝。
const arr = [1, [2, 3]];
const newArr = arr.slice();
newArr[1][0] = 9;
console.log(arr); // 输出: [1, [9, 3]]

3. 深拷贝(Deep Copy)

概念

深拷贝会递归地复制对象及其所有嵌套的属性,创建一个完全独立的新对象,新对象和原始对象在内存中没有任何共享部分。修改新对象的任何属性都不会影响原始对象。

实现方式
  • JSON.parse(JSON.stringify()):这是一种简单的深拷贝方法,但有局限性。它不能处理函数、Symbol 类型的属性、Date 对象、RegExp 对象等。
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 9;
console.log(original.b.c); // 输出: 2
  • 递归实现:自定义函数递归地复制对象和数组。
function deepClone(obj) {
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }

    let clone;
    if (Array.isArray(obj)) {
        clone = [];
        for (let i = 0; i < obj.length; i++) {
            clone[i] = deepClone(obj[i]);
        }
    } else {
        clone = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                clone[key] = deepClone(obj[key]);
            }
        }
    }
    return clone;
}

const original = { a: 1, b: { c: 2 } };
const deepCopy = deepClone(original);
deepCopy.b.c = 9;
console.log(original.b.c); // 输出: 2

相关文章:

  • 升级 SpringBoot3 全项目讲解 — 别再使用 Optional 了,请使用 Jspecify 来替代它
  • 怎么能在互联网上找到某个专业的专业资料?
  • 在 UniApp 项目中设置多语言
  • 2025.2.16机器学习笔记:TimeGan文献阅读
  • c#模拟鼠标点击左键
  • 【开源项目】图床工具Easyimage保姆级搭建
  • Windows编程:用 VS2019 编写C语言程序
  • 103-《茶靡花》
  • rtsp rtmp 跟 http 区别
  • Flask框架入门完全指南
  • 传统数组 vs vector和list
  • 【Python爬虫(5)】HTTP协议:Python爬虫的基石
  • Python版本管理器之Pyenv-win介绍与安装
  • DeepSeek笔记(二):DeepSeek局域网访问
  • 宝塔面板开始ssl后,使用域名访问不了后台管理
  • JSON入门略要
  • Lua 数据库访问
  • 30个常用的DEEPSEEK提示词
  • “单击以重新设置PIN”的解决方案
  • 算法-链表篇04-两两交换链表中的节点
  • 跨文化戏剧的拓荒者与传承者——洪深与复旦剧社的百年回响
  • 国务院关税税则委:调整对原产于美国的进口商品加征关税措施
  • 彭丽媛同巴西总统夫人罗桑热拉参观中国国家大剧院
  • 全国汽车以旧换新补贴申请量突破1000万份
  • 礼来公布头对头研究详细结果:替尔泊肽在所有减重目标中均优于司美格鲁肽
  • 巴西总统卢拉将访华