详解JS深拷贝与浅拷贝

yizhihongxing

详解JS深拷贝与浅拷贝

一、什么是拷贝

在JavaScript中,我们经常需要对一个数据进行拷贝,这里的拷贝指的是将一个数据重新复制一份,从而在新的数据上进行操作,而原始数据不会受到影响。拷贝手段分为两种:浅拷贝和深拷贝。

1.1 浅拷贝

浅拷贝就是将原始数据的引用复制一份给新的数据,这样新数据和原始数据指向同一块内存区域,因此对新数据进行操作,也会影响原始数据。

示例代码:

let obj = {a: 1, b: {c: 2}};
let newObj = obj;
newObj.a = 3;
newObj.b.c = 4;
console.log(obj); // {a: 3, b: {c: 4}}

可以看到,对 newObj 进行操作,同时也影响了 obj

1.2 深拷贝

深拷贝是将原始数据完整地复制一份给新的数据,新数据和原始数据没有任何联系,对新数据的操作也不会影响原始数据。

示例代码:

let obj = {a: 1, b: {c: 2}};
let newObj = JSON.parse(JSON.stringify(obj));
newObj.a = 3;
newObj.b.c = 4;
console.log(obj); // {a: 1, b: {c: 2}}
console.log(newObj); // {a: 3, b: {c: 4}}

可以看到,对 newObj 进行操作,并不影响 obj

二、浅拷贝的实现方法

2.1 Object.assign()

Object.assign()方法将所有的可枚举属性的值从一个或多个源对象复制到目标对象。它会先创建一个新对象,然后将源对象的属性拷贝到新对象上。

示例代码:

let obj1 = {a: 1,b: {c: 2}};
let obj2 = Object.assign({}, obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 4}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

2.2 扩展运算符 ...

扩展运算符 ... 也可以实现浅拷贝。它能够将一个数组或对象展开成一系列参数,方便地将其插入一个函数或对象字面量中。

示例代码:

let obj1 = {a: 1,b: {c: 2}};
let obj2 = {...obj1};
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 4}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

三、深拷贝的实现方法

3.1 手写递归函数

手写递归函数可以非常方便地实现深拷贝,它会遍历对象的所有属性和子属性,并将其转化为一个新的对象返回。

示例代码:

function deepClone(obj) {
  let newObj = Array.isArray(obj) ? [] : {};
  if (obj && typeof obj === "object") {
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        newObj[key] = deepClone(obj[key]);
      }
    }
  }
  else {
    newObj = obj;
  }
  return newObj;
}

let obj1 = {a: 1,b: {c: 2}};
let obj2 = deepClone(obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 2}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

3.2 使用第三方包

第三方包 lodash 中的 _.cloneDeep() 方法也可以实现深拷贝。这个方法可以递归地复制一个 JavaScript 对象。

示例代码:

const _ = require('lodash');

let obj1 = {a: 1,b: {c: 2}};
let obj2 = _.cloneDeep(obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 2}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

四、深度递归拷贝的注意事项

在深度递归拷贝中,需要注意以下几点:

  1. 对 Date、RegExp、Function 等对象无法进行深拷贝,需要特殊处理。
  2. 对于对象的循环引用,需要避免死循环。

五、总结

浅拷贝只是复制了一个对象的引用,而深拷贝则是复制了整个对象。使用递归函数实现深拷贝时,需要考虑到各种对象类型的情况。如果对数据的操作需要保证原始数据的不变性,建议使用深拷贝。

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

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

相关文章

  • javascript中setAttribute()函数使用方法及兼容性

    下面是关于JavaScript中setAttribute()函数的使用方法及兼容性的完整攻略: 一、语法概述 setAttribute()函数是一种在HTML和XML文档中设置属性的方法。它有两个参数: 属性名:要设置的属性名称 属性值:要设置的属性值 使用语法如下所示: element.setAttribute(attributeName, attribu…

    JavaScript 2023年5月27日
    00
  • Javascript 面向对象 重载

    JavaScript 是一种面向对象的编程语言,它支持函数重载,即同一函数名字,参数不同,对应的实现不同,JavaScript 可以通过这种方式实现函数重载。 什么是面向对象 面向对象(Object-Oriented Programming)是一种编程思想,它把对象作为程序的基本单元,将程序中的数据和操作数据的方法绑定在一起,以及保护数据的安全性。JavaS…

    JavaScript 2023年5月27日
    00
  • JS字符串累加Array不一定比字符串累加快(根据电脑配置)

    本文主要探讨 JavaScript 中字符串的拼接方式,包括使用数组累加字符串和直接字符串累加的方法,以及它们的性能比较。同时,本文还会详细介绍具体的测试方法和结果分析。 背景 在 JavaScript 中,字符串是一个常见的数据类型,我们通常会遇到需要拼接字符串的场景,比如将一个数组中的元素用逗号隔开成一个字符串。在这种场景下,我们通常采用以下两种方式: …

    JavaScript 2023年5月28日
    00
  • utf-8编码引起js输出中文乱码的解决办法

    下面是关于“utf-8编码引起js输出中文乱码”的解决办法的完整攻略。 问题描述 当我们在使用 JavaScript 输出中文时,如果页面的编码方式为 utf-8,那么经常会出现中文乱码的问题。就算页面的编码设置正确且合法,但还是无法避免可能遇到的中文输出乱码问题。接下来我们将介绍如何解决这个问题。 解决办法 一个常见的解决方法是将需要输出的中文字符转为 u…

    JavaScript 2023年5月20日
    00
  • JavaScript 巧学巧用

    JavaScript 巧学巧用完整攻略 JavaScript 是一种脚本语言,具有广泛的应用场景,尤其在 Web 开发中独树一帜。掌握 JavaScript 不仅可以增加开发效率,还可以开发出更加炫酷、交互性更强的网站和应用。本文将为大家介绍 JavaScript 巧学巧用的攻略,包括常用的技巧和使用示例。 1. 事件监听 事件监听是 JavaScript …

    JavaScript 2023年5月18日
    00
  • JavaScript实现进度条效果

    请看下面详细讲解“JavaScript实现进度条效果”的完整攻略。 1. 前置知识 在开始实现进度条效果之前,需要具备以下知识: HTML和CSS的基础知识 JavaScript的基本语法和DOM操作 2. 实现思路 实现进度条效果可以采用如下思路: 创建一个div元素,作为进度条的显示区域。 在CSS中设置进度条的基本样式,包括进度条的颜色、高度、圆角等。…

    JavaScript 2023年6月11日
    00
  • React组件化学习入门教程讲解

    下面我会详细讲解一下关于“React组件化学习入门教程讲解”的完整攻略: React组件化学习入门教程讲解 什么是React组件化 React.js是一个JavaScript库,可用于构建大型并高性能的web应用程序。React利用组件来管理界面上的各个部分。React的这种组件化开发方式是一种流行的前端编程模式,它使得应用程序更容易维护且易于扩展。在Rea…

    JavaScript 2023年6月11日
    00
  • Bootstrap编写一个在当前网页弹出可关闭的对话框 非弹窗

    让我来给你详细讲解一下如何使用Bootstrap编写一个在当前网页弹出可关闭的对话框。以下是具体的步骤: 版本说明 在编写本文时,Bootstrap 的最新版本为 v5.1.0,所以以下过程中的代码也是基于该版本编写的。 准备工作 在使用 Bootstrap 之前,你需要在你的网页中先引入相关的 CSS 和 JavaScript 文件。本文以 CDN 引入为…

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