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

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日

相关文章

  • JavaScript 嵌套函数指向this对象错误的解决方法

    JavaScript 嵌套函数指向this对象错误的解决方法攻略 在JavaScript中,嵌套函数的this对象指向可能会出现错误。这是因为在嵌套函数中,this的值会发生改变,指向不同的对象或者undefined。为了解决这个问题,我们可以采用以下两种方法。 1. 使用箭头函数 箭头函数是ES6引入的一种新的函数声明方式,它的this值是在定义时确定的,…

    other 2023年7月28日
    00
  • Centos8搭建基于kdc加密的nfs

    下面是CentOS 8搭建基于Kerberos加密的NFS(Network File System)的完整攻略。 1. 前置要求 在开始之前,需要满足以下要求: 已经安装CentOS 8系统,并设置静态IP地址; 已经配置好NFS服务和Kerberos认证服务。 2. 安装必要的软件包 在进行下一步之前,需要安装三个软件包。 sudo dnf install…

    other 2023年6月27日
    00
  • C#书写规范

    C#书写规范攻略 1. 命名规范 1.1 类和接口命名 类名和接口名应该使用帕斯卡命名法(PascalCase),即每个单词的首字母大写,不使用下划线或连字符。 类名应该是名词或名词短语,描述类的职责和功能。 接口名应该以\”I\”开头,后面跟随描述接口职责和功能的名词或名词短语。 示例: public class UserService { // 类的实现…

    other 2023年8月19日
    00
  • vue商城中商品“筛选器”功能的实现代码

    要在Vue商城中实现商品筛选器功能,需要先创建一个组件来处理筛选逻辑。该组件可以选择使用Vue的计算属性来处理筛选逻辑。 以下是实现商品筛选器功能的完整攻略: 1. 创建筛选器组件 首先,我们需要创建一个筛选器组件。该组件应该包含以下元素: input文本框,用于输入筛选关键字 下拉菜单,用于显示可用的筛选选项 筛选按钮,用于触发筛选操作 在组件中,我们需要…

    other 2023年6月27日
    00
  • es6英文文档翻译

    下面是“ES6英文文档翻译的完整攻略”的详细讲解,包括翻译流程、注意事项和两个示例等方面。 翻译流程 步骤1:选择文档 首先,需要选择一份 ES6 英文文档进行翻译。可以选择官方文档或者其他优质的文档,确保文档内容准确、全面、易懂。 步骤2:阅读文档 在开始翻译之前,需要先仔细阅读文档,了解文档的结构、内容和语言风格,为后续的翻译工作做好准备。 步骤3:逐句…

    other 2023年5月5日
    00
  • socket.on的用法

    问题描述 在使用Socket.io进行实时通信时,如何使用socket.on()方法收服务器发送的消息? 解决案 以下是使用socket.on()方法接收服务器发送的消息的解决方案: 方案1:使用匿名函数 可以使用匿名函数来接收服务器发送的消息。具体步骤如下: 在客户端代码中,使用socket.on()方法监听服务器发送的消息,并使用匿名函数处理消息: so…

    other 2023年5月7日
    00
  • Android布局优化之ViewStub控件

    当一个Activity包含大量的布局文件时,加载时间会变慢,影响用户体验。因此,Android中布局优化显得很有必要。ViewStub控件便是Android中一种有效的布局优化方式。 一、什么是ViewStub控件 在Android的布局文件中,可以使用ViewStub控件定义一个不可见的布局,这个布局不会在加载时被加载到内存中,只有在需要显示时才被实例化,…

    other 2023年6月27日
    00
  • 新建虚拟机与本机ping不通(一招解决)

    新建虚拟机与本机ping不通(一招解决) 问题描述 最近在使用虚拟机进行开发工作时,遇到了一个问题:新建的虚拟机无法与本机互ping,导致无法进行网络通信。经过调查,发现是虚拟机的网卡没有分配正确的IP地址。本文将介绍一种简单有效的方法来解决这个问题。 解决方法 首先,在虚拟机中打开终端或命令行界面,输入以下命令: ip addr show 这个命令用于显示…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部