JS实现数组深拷贝的方法分析

下面是一份详细的“JS实现数组深拷贝的方法分析”的攻略:

背景

在使用 JavaScript 中的数组时, 如果我们要将一个数组赋值给另一个变量, 只是简单地将数组变量赋给另一个变量,这样会导致两个变量指向同一个数组引用,即两个数组变量会指向同一个数组对象,如果只是数组的一些简单操作,这不会产生什么问题, 但如果涉及到多次修改某个数组,这时不停地修改一个数组会引用到其他变量之前时的状态,这样会影响程序运行结果。这时候,就需要对数组进行深拷贝。

方法

数组深拷贝有很多方法,比如使用 JSON 库深度复制、使用递归实现深度克隆、使用 ES6 的扩展符等等。下面将介绍其中两个方法:

方法一:JSON 库转换

const arr1 = [1, 2, { a: 3 }];
const arr2 = JSON.parse(JSON.stringify(arr1));

JSON 库中有两个方法:JSON.stringify()JSON.parse(),可以将任意复杂的东西转换成 JSON 字符串,再将这个 JSON 字符串解析成对象。在深拷贝数组中,我们可以利用 JSON 库的这两个方法:先把数组变成 JSON 字符串,再通过解析 JSON 字符串变成对象,从而达到深拷贝的目的。

但是,这种方法的缺陷是:它不能拷贝函数、正则、Date 等引用类型的值。

方法二:递归实现深度克隆

递归地从最简单的数据类型开始,每次返回时都进行一次克隆。遇到对象时,继续进行递归。

function deepClone(obj) {
  if (obj === null) {
    return null;
  }
  if (typeof obj !== "object") {
    return obj;
  }
  if (obj instanceof Date) {
    return new Date(obj.getTime());
  }
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
  const newObj = new obj.constructor();
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }
  return newObj;
}

const arr1 = [1, 2, { a: 3 }];
const arr2 = deepClone(arr1);

这种方法是通过递归实现深拷贝的。当拷贝的是基本类型时,直接返回该值,当是引用类型的时候,递归地拷贝该引用类型的值,并返回相应的克隆对象。这种方法比较完美地解决了 JSON 库方法的缺陷。

示例

下面两个示例将说明这两种方法分别是如何实现数组深拷贝的:

示例一:JSON 库转换

const arr1 = [1, 2, { a: 3 }, function () { console.log('hello') }];
const arr2 = JSON.parse(JSON.stringify(arr1));
arr2[2].a = 100;
console.log(arr1, arr2); // [1, 2, { a: 3 }, [Function]] [1, 2, { a: 100 }, null]

在这个示例中,我们把数组 arr1 赋值给 arr2 并使用 JSON 序列化和反序列化来完成深度复制。然后我们修改 arr2 的第三个元素,并输出 arr1 和 arr2。可以看到,虽然我们仅仅是修改了 arr2 的第三个元素,但 arr1 也跟着变了,即两个数组的第三个元素是不同的。

示例二:递归实现深度克隆

function deepClone(obj) {
  if (obj === null) {
    return null;
  }
  if (typeof obj !== "object") {
    return obj;
  }
  if (obj instanceof Date) {
    return new Date(obj.getTime());
  }
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
  const newObj = new obj.constructor();
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }
  return newObj;
}

const arr1 = [1, 2, { a: 3 }, function () { console.log('hello') }];
const arr2 = deepClone(arr1);
arr2[2].a = 100;
console.log(arr1, arr2); // [1, 2, { a: 3 }, [Function]] [1, 2, { a: 100 }, [Function]]

在这个示例中,我们使用递归方式来实现数组的深拷贝,同时也打印出 arr1 和 arr2 以验证两个数组对象的不同。由于我们使用了递归方式实现深拷贝,因此即使修改了 arr2 的第三个元素,arr1 也不会受到影响,两个数组对象是相互独立的。

结论

通过上面的两个示例,我们可以明确“JS实现数组深拷贝的方法分析”的攻略。

总的来说,利用 JSON 库的方法实现数组的深拷贝是最简单的方法,只需一些简单的代码即可。但是它有明显的缺陷,即无法深拷贝 Date、正则、函数等引用类型的值。

递归方式实现深拷贝是比较完美的解决方案,但需要考虑的细节会比较多,比如如何判断一个值是不是基本类型。如果拷贝的对象过于复杂,则递归方法的效率也比较低。

在实际应用中,需要根据具体的业务需求和性能要求选择不同的实现方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS实现数组深拷贝的方法分析 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • JavaScript程序员应该知道的45个实用技巧

    JavaScript程序员应该知道的45个实用技巧,是一篇有关于JavaScript编程的高质量技术指南。该指南列举了45个实用技巧,帮助JavaScript程序员更有效率和高效地工作。 以下是该攻略的完整说明: 目录 第1条:使用console.table格式化输出 第2条:使用Array.from()将类数组对象转换为数组 第3条:使用Array.isA…

    JavaScript 2023年5月18日
    00
  • js实现鼠标悬浮框效果

    JavaScript 实现鼠标悬浮框效果的过程主要分为以下几步: 1. 创建 HTML 结构 首先需要在 HTML 中定义框架,例如容器、容器内的内容、触发事件的 DOM 元素等。其中包含一个容器作为悬浮框,在鼠标触发事件后自动显示,同时鼠标移出事件后自动隐藏。 例如: <div class="parent"> <but…

    JavaScript 2023年6月11日
    00
  • JavaScript中使用Math.PI圆周率属性的方法

    当我们需要计算几何图形的面积或周长时,经常需要用到圆周率常数 π (pi)。在 JavaScript 中,我们可以使用 Math.PI 属性来访问这个数值,下面是详细步骤: 步骤1:访问Math.PI常数 Math.PI 属性中存储着圆周率的数值。可以通过直接使用 Math.PI 的方式来访问这个属性。代码如下: console.log(Math.PI); …

    JavaScript 2023年5月28日
    00
  • CSS对Web页面载入效率的影响分析总结

    CSS对Web页面载入效率的影响分析总结 CSS样式表对Web页面的载入效率有着重要的影响,不合理使用会导致页面的加载速度过慢,影响用户访问体验。因此,优化CSS样式表的使用对Web页面性能优化至关重要。下面将从以下几个方面对CSS对Web页面载入效率的影响进行总结。 CSS文件大小的影响 CSS文件大小是影响Web页面载入效率的主要因素之一。较大的CSS文…

    JavaScript 2023年6月10日
    00
  • 超全面的javascript中变量命名规则

    下面我将为大家详细讲解“超全面的JavaScript中变量命名规则”的攻略。 1. 变量命名规则概述 在JavaScript中,为变量命名有一定的规则。以下是命名变量的一般规则: 变量名可以由字母、数字、下划线或美元符号组成,但第一个字符不能是数字。 变量名可以含有字母的大小写,但建议使用小写字母。 变量名不能使用JavaScript中的关键字,如:if、e…

    JavaScript 2023年5月19日
    00
  • js实现键盘自动打字效果

    实现键盘自动打字效果可以分为以下几个步骤: 1. 获取需要自动打印的文本 首先,需要准备需要打印的文本内容。这可以通过在HTML中插入一个元素,并给该元素设置一个文本内容,然后使用JavaScript获取该元素的innerText或innerHTML属性值,就可以得到需要打印的文本。 示例代码 HTML代码: <p id="text&quot…

    JavaScript 2023年5月28日
    00
  • js replace(a,b)之替换字符串中所有指定字符的方法

    关于 JavaScript 中字符串替换方法 replace(a, b) 的使用,我来给你详细讲解一下。 基本语法 replace() 方法用于替换字符串中的指定值。该方法可以接收两个参数: 要替换的字符串 替换后的字符串 语法如下: string.replace(searchValue, replaceValue) 其中,searchValue 是要替换的…

    JavaScript 2023年5月28日
    00
  • JS常见简单正则表达式验证功能小结【手机,地址,企业税号,金额,身份证等】

    JS常见简单正则表达式验证功能小结 在Web开发中,我们会经常需要验证用户提交的数据是否符合特定的格式。使用正则表达式是一种很方便的方式,本篇攻略旨在介绍常见的一些正则表达式验证功能。 手机号码验证 function isValidPhoneNumber(phoneNumber) { const regex = /^1[3-9]\d{9}$/; return…

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