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

使用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


http://www.kler.cn/a/548736.html

相关文章:

  • 单链表的概念,结构和优缺点
  • openharmony系统移植之显示驱动框架从framebuffer升级为drm(linux-5.10)
  • 【JVM系列】谈一谈JVM调优
  • 【Leetcode】解锁二分查找:突破解题瓶颈的关键技巧
  • Java和JavaScript当中的json对象和json字符串分别讲解
  • 栈的深度解析:从基础实现到高级算法应用——C++实现与实战指南
  • 清华大学×DeepSeek 使用手册 2.0:《DeepSeek如何赋能职场应用?》(文末附下载链接)
  • DeepSeek-R1论文阅读及蒸馏模型部署
  • SpringBoot:使用spring-boot-test对web应用做单元测试时如何测试Filter?
  • C++11新特性之final
  • 【吾爱出品】 视频批量分段工具
  • 物联网行业通识:从入门到深度解析
  • 深入解析SVG图片原理:从基础到高级应用
  • 类和对象(5)——抽象类和接口
  • webassembly009 transformers.js 网页端侧推理 whisper-web的AudioManager组件
  • 42 接雨水
  • 【数据结构】 栈和队列
  • 网剧《一念逍遥》正式启动筹备
  • vLLM专题(二):安装-CPU
  • 【Python】Python入门基础——环境搭建