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日

相关文章

  • 详解JSON Web Token 入门教程

    题目中提到的“详解JSON Web Token 入门教程”的完整攻略,应该包括以下内容: 1. 什么是JSON Web Token 首先,我们需要明确JSON Web Token(JWT)是什么。JWT是一种用于身份验证的开放标准,它允许在网络上传输数据,以确保数据在传输过程中不会被篡改。JWT通常用来描述两个系统之间的请求和响应之间的详细信息。 2. JW…

    JavaScript 2023年5月27日
    00
  • js自调用匿名函数的三种写法(推荐)

    下面是JS自调用匿名函数的三种写法攻略: 1. 包裹执行 最常见的自调用匿名函数就是包裹执行(也称为自调用函数表达式,IIFE)。这种写法在函数表达式后紧跟一个括号,表示调用这个函数。其主要目的是防止变量污染全局作用域。 标准写法: (function() { // 在这里编写你的代码 })(); 可以使用 arrow function (ES6+)简化写法…

    JavaScript 2023年5月27日
    00
  • js中window.open()的所有参数详细解析

    下面我来为你详细讲解“js中window.open()的所有参数详细解析”。 1. window.open()的用途 window.open()是JavaScript中的一个方法,它可以通过创建新的浏览器窗口或标签页来打开一个新的URL地址。 2. window.open()的语法 window.open([URL], [name], [features],…

    JavaScript 2023年6月11日
    00
  • 详细介绍8款超实用JavaScript框架

    详细介绍8款超实用JavaScript框架 JavaScript 拥有十分丰富的生态系统,框架也是其中不可忽视的一部分。下面是8款超实用的 JavaScript 框架,它们受欢迎的原因在于它们能帮助程序员节省时间和提高效率。 1. jQuery jQuery 是最受欢迎的 JavaScript 框架之一。jQuery 旨在简化 HTML 文档遍历、事件处理、…

    JavaScript 2023年5月18日
    00
  • JS AJAX前台如何给后台类的函数传递参数

    JS AJAX(Asynchronous JavaScript and XML)使得前端能够异步发起HTTP请求,获取数据,并更新页面,而无需刷新整个页面。在传递参数方面,AJAX提供了多种方式: 通过URL传递参数 通过在URL后面添加查询字符串,即可将参数传递给后台。 let xhr = new XMLHttpRequest(); let url = &…

    JavaScript 2023年6月11日
    00
  • 教你用几十行js实现很炫的canvas交互特效

    关于“教你用几十行js实现很炫的canvas交互特效”的完整攻略,我将从以下几个方面进行详细讲解: 准备工作 在实现交互特效之前,我们需要准备一些必要的工作:首先是引入Canvas标签;其次是编写Canvas绘制所需的HTML、CSS及JavaScript代码;最后还需要确定绘制的内容和样式。 创建画布并绘制基础图形 在Canvas中创建画布并绘制基础图形是…

    JavaScript 2023年6月10日
    00
  • 浅谈前端JS沙箱实现的几种方式

    浅谈前端JS沙箱实现的几种方式 什么是前端JS沙箱 前端JS沙箱是一种能够隔离和保护页面中各种Javascript代码的运行环境,防止其中不受控制的代码对网页造成损害,同时也保证了JS代码的安全性。实现前端JS沙箱的方式主要有以下几种: 方式一:使用iframe和srcdoc 使用iframe和srcdoc的方式来创建前端JS沙箱,可以让我们构建一个独立的执…

    JavaScript 2023年6月11日
    00
  • 详解javascript函数的参数

    下面就详细讲解“详解JavaScript函数的参数”的完整攻略。 1. 简介 在 JavaScript 函数定义中,可以传递任意数量的参数,包括数字、字符串、对象等,这些参数可以在函数体中使用。函数的参数可以被看做是可以传递给函数的变量,它们是函数体内部的局部变量。 2. 基本用法 JavaScript 函数定义中可以传递任意数量的参数,这些参数通过逗号隔开…

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