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

yizhihongxing
  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日

相关文章

  • angularJs中datatable实现代码

    下面给出AngularJS中datatable实现代码的完整攻略,这里使用的是AngularJS版本为1.x,实现过程中需要使用一些第三方库来支持。攻略分成以下几个步骤: 步骤一 安装必需的依赖 在开始之前,你需要在本地安装以下库: jQuery:用于操作DOM和事件处理 Bootstrap:用于样式 AngularJS:主要的MVC框架 <!– j…

    JavaScript 2023年6月11日
    00
  • 详解vue的双向绑定原理及实现

    关于《详解vue的双向绑定原理及实现》的攻略,我们可以分为以下几个部分进行讲解: 一、什么是双向绑定?为何要使用双向绑定? 双向绑定 Vue.js 中的双向绑定是将数据与视图进行双向绑定。在数据发生变化时,视图会自动更新并显示最新的状态;而在用户交互改变视图的值时,数据也会自动更新。 使用双向绑定的好处 使用双向绑定可以使我们写的代码更加简洁明了,减少了大量…

    JavaScript 2023年6月11日
    00
  • 常见JS验证脚本汇总

    “常见JS验证脚本汇总”是一篇介绍JavaScript验证脚本的文章。JavaScript验证脚本用来验证表单输入的内容是否符合预期,可以提高表单的准确性和安全性。以下是详细的攻略: 标题 介绍 在介绍JavaScript验证脚本之前,需要先了解HTML表单的基本结构和form元素的常见属性。 JavaScript验证脚本的基本结构 JavaScript验证…

    JavaScript 2023年6月10日
    00
  • js 程序执行与顺序实现详解

    JS程序执行与顺序实现详解 JS是一门单线程语言,指在一个时间只执行一个任务。虽然JS是单线程语言,但是它可以利用事件循环和回调实现异步编程。 1. JS代码的执行顺序 JS代码是从上往下一行一行执行的,但是在执行JS代码时,遇到如下情况就会把当前任务挂起,去执行其他任务: 等待Web API返回结果,例如:发起Ajax请求等。 等待定时器。 等待事件发生。…

    JavaScript 2023年5月27日
    00
  • 《JavaScript高级程序设计》阅读笔记(三) ECMAScript中的引用类型

    《JavaScript高级程序设计》阅读笔记(三) ECMAScript中的引用类型 引用类型 在 ECMAScript 中,引用类型指的是一种数据类型,这种数据类型是由多个不同的属性组成的对象。 Object 类型 Object 类型是 ECMAScript 中最基本的数据类型,也可以称之为引用类型的总称。对象是由键值对组成的无序集合。 创建一个 Obje…

    JavaScript 2023年5月27日
    00
  • javascript 浏览器判断 绑定事件 arguments 转换数组 数组遍历

    一、javascript浏览器判断 要在javascript中进行浏览器判断,可以通过navigator对象获取浏览器的信息。常用的属性包括: navigator.userAgent:获取完整的userAgent字符串; navigator.appName:获取浏览器的名称; navigator.appVersion:获取浏览器的版本号; navigator…

    JavaScript 2023年6月11日
    00
  • JavaScript实现数字数组正序排列的方法

    下面是实现数字数组正序排列的方法的攻略。 步骤一:使用JavaScript原生方法实现排序 JavaScript提供了sort()方法来对数组进行排序。sort()方法默认按照字典顺序排序,可以使用回调函数来实现数字的正序排列。回调函数接收两个参数,分别代表即将比较的元素a和b,通过返回值可以决定排列顺序。 let arr = [3,6,1,2,8,4]; …

    JavaScript 2023年5月27日
    00
  • Javascript toFixed 方法

    以下是关于JavaScript toFixed方法的完整攻略。 JavaScript toFixed方法 JavaScript toFixed()方法是Number对象的一个方法,用于将数字转换字符串,并保留指定的小数位数。我们可以使用toFixed()方法来格式化数字,使其符合我们的需求。 下面是一个使用()方法的示例: var num = 3.14159…

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