JavaScript深拷贝的几种实现方法实例

  1. 为什么需要深拷贝?

在 JavaScript 中,对象和数组是通过引用赋值的方式传递的。如果直接将一个对象或数组赋值给另一个变量,那么这两个变量其实指向的是同一个对象或数组。因此,如果修改其中一个变量所指向的对象或数组的值,那么另一个变量也会受到影响。这就是浅拷贝的特点。为了避免这种情况的发生,我们需要进行深拷贝,即创建一个新的对象或数组,其中所有的值都是原来对象或数组中的值的副本,互不相干。

  1. 深拷贝的几种实现方式

2.1 手动递归实现

最原始的实现方式就是手动递归复制,代码如下所示:

function deepClone(obj) {
  // 首先判断对象是否为null或者不是对象、数组类型
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 根据obj的类型创建一个对应的空对象或数组
  const newObj = Array.isArray(obj) ? [] : {};

  // 遍历obj的所有属性,递归复制
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }

  return newObj;
}

2.2 使用JSON.stringify和JSON.parse

这种方式是将对象转换成JSON字符串,再将JSON字符串转换回对象。这种方法虽然简单,但不能处理函数、undefined、RegExp等特殊类型数据。同时,属性中的循环引用也会导致错误。

function deepClone(obj) {
  return JSON.parse(JSON.stringify(obj));
}

2.3 使用lodash库

Lodash库是一个非常流行的JavaScript工具库,其中包含了深拷贝函数cloneDeep,使用很方便。

const _ = require('lodash');

function deepClone(obj) {
  return _.cloneDeep(obj);
}
  1. 示例演示

3.1 手动递归实现示例

const obj = {
  name: 'Tom',
  age: 20,
  shape: {
    weight: 70,
    height: 180,
  },
  hobbies: ['reading', 'running'],
};

const newObj = deepClone(obj);

newObj.name = 'Jerry';
newObj.shape.weight = 65;
newObj.hobbies.push('cycling');

console.log(obj);
console.log(newObj);

输出结果如下:

{
  name: 'Tom',
  age: 20,
  shape: { weight: 70, height: 180 },
  hobbies: [ 'reading', 'running', 'cycling' ]
}
{
  name: 'Jerry',
  age: 20,
  shape: { weight: 65, height: 180 },
  hobbies: [ 'reading', 'running', 'cycling' ]
}

可以看出,修改newObj中的属性并不会影响到原来的obj对象。

3.2 JSON.stringify和JSON.parse示例

const obj = {
  name: 'Tom',
  age: 20,
  shape: {
    weight: 70,
    height: 180,
  },
  hobbies: ['reading', 'running'],
};

const newObj = deepClone(obj);

newObj.name = 'Jerry';
newObj.shape.weight = 65;
newObj.hobbies.push('cycling');

console.log(obj);
console.log(newObj);

输出结果如下:

{
  name: 'Tom',
  age: 20,
  shape: { weight: 70, height: 180 },
  hobbies: [ 'reading', 'running' ]
}
{
  name: 'Jerry',
  age: 20,
  shape: { weight: 65, height: 180 },
  hobbies: [ 'reading', 'running', 'cycling' ]
}

同样可以看出,修改newObj中的属性并不会影响到原来的obj对象。

综上所述,每种实现方式都有自己的优缺点,具体使用要根据场景需求进行选择。如果需要更加高效的深拷贝实现,则可以使用immutable.js等工具库。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript深拷贝的几种实现方法实例 - Python技术站

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

相关文章

  • JavaScript数组常用方法解析及数组扁平化

    首先我们来分别解析JavaScript数组常用方法和数组扁平化。 Part 1:JavaScript数组常用方法解析 JavaScript数组是一种非常常用的数据类型,有很多常用方法可以操作数组。以下是一些常用方法的详细解析: push():向数组的末尾添加一个元素 语法:array.push(element1, element2, …, element…

    JavaScript 2023年5月27日
    00
  • 详解JavaScript的表达式与运算符

    详解JavaScript的表达式与运算符 什么是表达式与运算符? 表达式(Expression)是一个可求值的代码片段,它可以包含变量、运算符、函数调用等,并最终会返回一个值。JavaScript 中的表达式有很多种类,如算术表达式、赋值表达式、比较表达式、逻辑表达式等。 运算符(Operator)则是用来处理表达式的一种特殊符号,它可以识别操作数之间的关系…

    JavaScript 2023年5月19日
    00
  • ES6如何将 Set 转化为数组示例详解

    当需要将ES6 Set类型转化成数组进行处理时,我们可以使用一些内置的方法来完成这个过程。 使用Array.from()方法 const mySet = new Set(["hello", "world"]); const myArr = Array.from(mySet); console.log(myArr); 在…

    JavaScript 2023年5月27日
    00
  • javascript中this做事件参数相关问题解答

    下面是完整攻略: JavaScript中this做事件参数相关问题解答 背景 在JavaScript中,我们经常会用到this关键字。尤其在事件处理函数中,this作为事件参数被广泛使用。但是,this在不同的情况下有不同的指向,在事件处理函数中可能会出现一些问题,本文将对这些问题进行解答。 this指向 在JavaScript中,this的指向是动态的,取…

    JavaScript 2023年6月11日
    00
  • JavaScript学习点滴 call、apply的区别

    讲解“JavaScript学习点滴 call、apply的区别”的完整攻略如下: 一、call和apply的概念 在Javascript中,所有对象都可以调用call和apply方法,它们的作用都是改变函数体内this的指向。两者的区别在于传入参数的形式不同。 call和apply都是定义在Function.prototype上的方法,因此可以被所有的函数对…

    JavaScript 2023年6月10日
    00
  • html的DOM中document对象images集合用法实例

    下面是关于“HTML的DOM中document对象images集合用法实例”的完整攻略: 什么是DOM中的document对象images集合 在HTML的DOM中,每个图片元素都被定义为标签。而通过document对象的images集合,我们可以获取到文档中的所有图片元素,并对其进行一系列的操作,比如更改图片路径、设置图片样式等等。 document对象i…

    JavaScript 2023年6月10日
    00
  • Javascript Date setFullYear() 方法

    以下是关于JavaScript Date对象的setFullYear()方法的完整攻略,包括两个示例说明。 JavaScript Date对象的setFullYear()方法 JavaScript Date对象的setFullYear()方法设置日期对象的年份部分。该方法接受一个整数,表示要设置的年份。如果该参数超出了JavaScript所能表示的范围,则自…

    JavaScript 2023年5月11日
    00
  • JS封装cookie操作函数实例(设置、读取、删除)

    下面我来为你详细讲解“JS封装cookie操作函数实例(设置、读取、删除)”的完整攻略。 什么是cookie cookie 是浏览器用于存储用户信息的一种机制。当我们需要在应用程序之间共享数据时,可以使用 cookie 来存储数据。它是一种名为键-值对的数据结构,可以存储在浏览器中的本地电脑上,并在将来的会话之间使用。 如何进行cookie操作 我们可以使用…

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