js深拷贝与浅拷贝一文彻底搞懂

yizhihongxing

JS深拷贝与浅拷贝一文彻底搞懂

什么是深拷贝与浅拷贝

在JavaScript中,由于对象和数组是通过引用传递的,所以需要特别注意拷贝的方式。拷贝的方式可以分为两种:深拷贝和浅拷贝。

深拷贝会复制一个对象或数组,包括其所有的嵌套属性和子元素,而浅拷贝只是复制了对象或数组本身,并没有复制嵌套的属性或子元素。

深拷贝

以下是一种常见的深拷贝方法,通过递归函数来实现:

function deepClone(obj) {
  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 originalObj = {
  a: 1,
  b: {
    c: 2
  }
};
let clonedObj = deepClone(originalObj);
originalObj.b.c = 3;

console.log(originalObj); // {a: 1, b: {c: 3}}
console.log(clonedObj); // {a: 1, b: {c: 2}}

在这个示例中,我们创建了一个原始对象originalObj,然后使用deepClone方法进行深拷贝得到一个新的对象clonedObj。接着,我们对原始对象originalObjb.c属性进行修改,并输出两个对象的值。可以发现,修改原始对象并不会影响到克隆对象,证明深拷贝是生效的。

浅拷贝

以下是三种常见的浅拷贝方法:

方法一:对象的扩展运算符(Spread Operator)

let originalObj = {
  a: 1,
  b: {
    c: 2
  }
};
let copiedObj = {...originalObj};
originalObj.b.c = 3;

console.log(originalObj); // {a: 1, b: {c: 3}}
console.log(copiedObj); // {a: 1, b: {c: 3}}

在这个示例中,我们使用了对象的扩展运算符...进行浅拷贝。新对象copiedObj中的b属性与原始对象中的b属性指向同一个引用,所以修改原始对象中的b.c属性也会影响到新对象中的b.c属性。

方法二:Object.assign()方法

let originalObj = {
  a: 1,
  b: {
    c: 2
  }
};
let copiedObj = Object.assign({}, originalObj);
originalObj.b.c = 3;

console.log(originalObj); // {a: 1, b: {c: 3}}
console.log(copiedObj); // {a: 1, b: {c: 3}}

在这个示例中,我们使用了Object.assign()方法进行浅拷贝。同样,新对象copiedObj中的b属性与原始对象中的b属性指向同一个引用,修改原始对象中的b.c属性也会影响到新对象中的b.c属性。

方法三:数组的slice()方法

let originalArr = [1, 2, 3];
let copiedArr = originalArr.slice();
originalArr.push(4);

console.log(originalArr); // [1, 2, 3, 4]
console.log(copiedArr); // [1, 2, 3]

在这个示例中,我们使用了数组的slice()方法进行浅拷贝。新数组copiedArr与原始数组中的元素是值拷贝关系,因此修改原始数组并不会影响到新数组。

总结

在JavaScript中,深拷贝和浅拷贝是两种常见的拷贝方式。深拷贝会复制一个对象或数组,包括其所有的嵌套属性和子元素,而浅拷贝只是复制了对象或数组本身,并没有复制嵌套的属性或子元素。

对于深拷贝,可以使用递归函数的方式进行实现。对于浅拷贝,可以使用对象的扩展运算符、Object.assign()方法或数组的slice()方法进行实现。在实际应用中,需要根据具体情况选择合适的拷贝方式,特别是对于嵌套的对象或数组,需要特别注意选择深拷贝或浅拷贝方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js深拷贝与浅拷贝一文彻底搞懂 - Python技术站

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

相关文章

  • css @import url加载样式应用深入分析

    当我们需要加载一些额外的CSS文件来覆盖默认样式或者添加新的样式时,我们可以使用CSS的@import规则。@import规则用于导入一个CSS文件,并且可以在导入的CSS文件中再次使用@import规则,从而形成一个CSS文件的引用链。下面详细介绍如何使用@import规则加载样式,并且分析其应用深入。 一、@import规则的语法 @import规则可以…

    other 2023年6月25日
    00
  • 应用程序无法正常启动提示0xc000007b(内存错误)

    当用户在启动某些应用程序时,可能会收到以下错误提示:“应用程序无法正常启动,错误代码为0xc000007b(内存错误)”。这个错误通常是由于系统上缺少必需的运行库文件(DLL)或这些文件损坏而引起的。为了解决这个问题,你可以采取如下步骤: 1. 安装或重新安装所需的运行库文件 首先,你需要确定应用程序需要哪些运行库文件,然后从正确的渠道下载和安装这些文件。运…

    other 2023年6月25日
    00
  • html5 video标签屏蔽右键视频另存为的js代码

    要实现html5 video标签屏蔽右键视频另存为,我们可以使用Javascript代码来解决。具体的实现过程如下: 1. 创建一个video标签 首先,我们需要在HTML中创建一个video标签,并指定要加载的视频文件路径。 <video id="myVideo" controls preload="metadata&q…

    other 2023年6月27日
    00
  • sql获取当前时间(日期)

    获取当前时间(日期)在SQL中是常见的需求,在不同的数据库管理系统中实现方法略有不同,但是基本思路相同。下面我将针对常见的SQL数据库管理系统,比如MySQL、Oracle、SQL Server等,给出获取当前时间(日期)的完整攻略。 MySQL MySQL中有NOW()函数可以直接获取当前的日期和时间,该函数返回一个DATETIME格式的值,即年-月-日 …

    其他 2023年4月16日
    00
  • javascript操作ASP.NET服务器控件

    首先讲解一下”javascript操作ASP.NET服务器控件”的完整攻略。 操作ASP.NET服务器控件的前提条件 在进行javascript操作ASP.NET服务器控件之前,我们需要先了解几个前提条件: 确保已加载jquery或其他js类库 引用ASP.NET服务器控件的ID或Class名称 掌握ASP.NET服务器控件的相关属性和事件 操作ASP.NE…

    other 2023年6月26日
    00
  • 解决Spring AOP拦截抽象类(父类)中方法失效问题

    要解决Spring AOP拦截抽象类(父类)中方法失效问题,我们需要在拦截器中使用一个aspectj工具方法来处理。下面是具体的攻略: 1. 继承AbstractAutoProxyCreator类 在Spring中,我们通常使用AbstractAutoProxyCreator类作为自动代理创建器,所以我们需要继承它。重写其中的postProcessAfter…

    other 2023年6月27日
    00
  • DevOps自动化组件RUNDECK开发部署使用说明

    DevOps自动化组件RUNDECK开发部署使用说明 什么是RUNDECK? RUNDECK是一款自动化工具,可以用于在数据中心或云环境中自动化各种日常任务和操作。它提供了一个中心化的控制面板,可以管理和控制不同的任务,同时可以在多个服务器上自动化地运行任务。 RUNDECK安装部署 环境准备 服务器操作系统:CentOS 7.x 或 RHEL 7.x 预装…

    other 2023年6月27日
    00
  • Java中的抽象类和接口你了解吗

    Java中的抽象类和接口是两种重要的概念,它们可以帮助开发者提高代码的可复用性和可维护性。下面,让我详细讲解一下Java中的抽象类和接口。 什么是抽象类? 抽象类是一个声明了抽象方法的类。抽象方法是一种没有实现的方法,在抽象类中只能声明,不能实现,具体实现由继承抽象类的子类来完成。抽象类本身不能实例化。 抽象类一般用于定义一些共有的行为和属性,具体的实现交给…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部