JavaScript深拷贝与浅拷贝实现详解

JavaScript深拷贝与浅拷贝实现详解

什么是拷贝?

在JavaScript中,我们经常需要将对象或者数组进行复制操作,这被称为拷贝。在拷贝过程中,我们需要注意两个概念:浅拷贝和深拷贝。

什么是浅拷贝?

浅拷贝仅仅是复制了对象或数组的引用,而并没有克隆对象或数组。也就是说,对于被拷贝的对象或数组,它们的属性仍然指向原对象或数组中的属性。浅拷贝通常使用的方法有:

Object.assign方法

const obj = {a: 1, b: 2};
const copy = Object.assign({}, obj);
console.log(copy); // {a: 1, b: 2}

扩展运算符(...)

const obj = {a: 1, b: 2};
const copy = {...obj};
console.log(copy); // {a: 1, b: 2}

需要注意的是,浅拷贝只能复制对象或数组的一层属性,如果被拷贝的对象或数组中还有嵌套的对象或数组,浅拷贝并不会进行递归拷贝。

什么是深拷贝?

深拷贝则是完全复制了对象或数组,包括对象或数组中的所有嵌套对象或数组,新的对象或数组和原对象或数组完全独立无关。深拷贝通常使用的方法有:

JSON.parse和JSON.stringify方法

const obj = {a: 1, b: {c: 2}};
const copy = JSON.parse(JSON.stringify(obj));
console.log(copy); // {a: 1, b: {c: 2}}

需要注意的是,因为JSON.stringify方法无法处理Symbol、Date、函数等特殊类型,因此在深拷贝过程中这些类型会被忽略掉。

递归拷贝

function deepCopy(obj) {
  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  } else if (typeof obj === 'object' && obj !== null) {
    const copy = {};
    Object.keys(obj).forEach((key) => {
      copy[key] = deepCopy(obj[key]);
    });
    return copy;
  } else {
    return obj;
  }
}

const obj = {a: 1, b: {c: 2}};
const copy = deepCopy(obj);
console.log(copy); // {a: 1, b: {c: 2}}

递归拷贝可以完美地复制对象或数组中的所有属性,除了Symbol、Date、函数等特殊类型。

示例说明

示例一

const obj = {
  a: 1,
  b: {
    c: 2
  }
};
const copy1 = Object.assign({}, obj);
const copy2 = {...obj};
const copy3 = JSON.parse(JSON.stringify(obj));
const copy4 = deepCopy(obj);

obj.b.c = 3;

console.log(copy1); // {a: 1, b: {c: 3}}
console.log(copy2); // {a: 1, b: {c: 3}}
console.log(copy3); // {a: 1, b: {c: 2}}
console.log(copy4); // {a: 1, b: {c: 2}}

在这个示例中,我们首先定义了一个对象obj,其中包含一个嵌套对象b。然后我们使用了四种方法分别对obj进行了浅拷贝和深拷贝。接着,我们修改了obj.b.c的值为3,然后输出了四个拷贝的结果。可以看到,浅拷贝的两种方法都会随着原对象的改变而发生改变,而深拷贝的两种方法则不受原对象的影响。

示例二

const arr = [1, 2, [3, 4]];
const copy1 = arr.slice();
const copy2 = [...arr];
const copy3 = JSON.parse(JSON.stringify(arr));
const copy4 = deepCopy(arr);

arr[2][0] = 5;

console.log(copy1); // [1, 2, [5, 4]]
console.log(copy2); // [1, 2, [5, 4]]
console.log(copy3); // [1, 2, [3, 4]]
console.log(copy4); // [1, 2, [3, 4]]

在这个示例中,我们首先定义了一个数组arr,其中包含一个嵌套数组。然后我们使用了四种方法分别对arr进行了浅拷贝和深拷贝。接着,我们修改了arr[2][0]的值为5,然后输出了四个拷贝的结果。可以看到,浅拷贝的两种方法都会随着原数组的改变而发生改变,而深拷贝的两种方法则不受原数组的影响。

总结

浅拷贝和深拷贝是JavaScript中常用的拷贝方式,每种方式都有其优缺点。在实际应用中,我们需要根据具体的情况选择合适的拷贝方式,以保证拷贝的结果符合预期。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript深拷贝与浅拷贝实现详解 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • javascript中SetInterval与setTimeout的定时器用法

    关于JavaScript中的SetInterval和setTimeout定时器用法,我会给你一些详细的说明。 SetInterval和setTimeout的简介 SetInterval和setTimeout是JavaScript中非常常用、常见的两个定时器,它们可以让我们在一个指定的时间间隔或者一次性的延时之后执行相应的代码。具体来说: SetInterva…

    JavaScript 2023年6月11日
    00
  • js内置对象处理_打印学生成绩单的简单实现

    下面将详细讲解“js内置对象处理_打印学生成绩单的简单实现”的完整攻略。 前置知识 在学习这个问题之前,你需要了解以下知识: JavaScript对象和数组的基础概念 for循环和while循环的基础使用方式 键值对的概念 代码的排版和注释 控制台输出console.log()的使用方法 如果你对以上概念不熟悉,建议先学习相关的基础教程。 问题描述 在这个问…

    JavaScript 2023年5月28日
    00
  • JS数组扁平化、去重、排序操作实例详解

    JS数组扁平化、去重、排序操作实例详解 在JS编程中,经常需要对数组进行处理,比如将一个多维数组“扁平化”成一维数组、去掉数组中的重复元素、按照一定规则排序等操作。本文将介绍如何在JS中实现数组的扁平化、去重和排序操作,并给出相应的代码示例。 JS数组扁平化 所谓的数组扁平化,就是将一个嵌套多层的数组变成一个一维数组。比如: const arr = [1, …

    JavaScript 2023年5月27日
    00
  • JS中的回调函数实例浅析

    JS中的回调函数实例浅析 什么是回调函数 回调函数是一种在函数执行完毕后,将另一个函数作为参数传递给它,并在后者执行的函数。它的特点是:回调函数是作为参数传递给另一个函数的,当另一个函数执行完毕后,回调函数才会被执行。 回调函数通常用于异步编程中,由于JavaScript是单线程的,异步调用的函数执行完毕后需要得到回调函数的执行结果,以便继续执行后续的代码。…

    JavaScript 2023年5月28日
    00
  • js流动式效果显示当前系统时间

    实现JS流动式效果显示当前系统时间,可以通过以下步骤实现: 第一步:获取当前时间 JavaScript中可以通过Date()对象获取当前的系统时间。 var now = new Date(); var hour = now.getHours(); //小时 var minute = now.getMinutes(); //分钟 var second = no…

    JavaScript 2023年5月27日
    00
  • ES6 Class中实现私有属性的一些方法总结

    下面是关于“ES6 Class中实现私有属性的一些方法总结”的完整攻略: 1. 私有属性的概念 在ES6的Class中,私有属性是指只能在类内部访问,而无法在类外部访问的属性。目前,ES6并不支持直接定义私有属性,但是可以通过一些方法实现类似于私有属性的效果。 2. 实现私有属性的方法 以下是几种实现私有属性的方法: 2.1 在构造函数中定义私有属性 这种方…

    JavaScript 2023年6月10日
    00
  • JavaScript promise的使用和原理分析

    下面是关于“JavaScript promise的使用和原理分析”的完整攻略。 简介 Promise 是 JavaScript 中一种较新的异步编程解决方案,用于解决回调函数嵌套过多的问题,使异步代码更加易于维护和阅读。Promise 对象代表了未来将要发生的事件,它是异步操作的结果的一个临时存储对象,可以让我们像同步操作一样去处理异步操作的结果。 Prom…

    JavaScript 2023年5月28日
    00
  • js 声明数组和向数组中添加对象变量的简单实例

    下面是关于JS声明数组和向数组中添加对象变量的简单实例的完整攻略。 一、JS声明数组 在JS中声明数组可以使用Array关键字或简单的方括号[]来完成,比如: // 使用Array关键字声明 let arr1 = new Array(); // 简单使用方括号声明 let arr2 = []; 以上两种声明方式是等价的。 二、向数组中添加对象变量 要向JS数…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部