JavaScript如何实现数据的深拷贝、浅拷贝?

简介: JavaScript如何实现数据的深拷贝、浅拷贝?

原文合集地址如下,有需要的朋友可以关注

本文地址

什么是深浅拷贝

说到深浅拷贝就得提起JavaScript中的数据类型之前的文章中有介绍过,这里就不再细说了。
浅拷贝:对基本数据类型进行值复制,对引用数据类型复制引用地址。浅拷贝会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果拷贝的是像对象这样的引用对象,那么浅拷贝会复制引用指向堆内存地址,因此源对象和拷贝对象会共享属性。
深拷贝:对基本数据类型进行值复制,对引用数据类型递归复制。深拷贝会另外创造一个一摸一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
区别举例:

// 原始对象
let obj = {
   
  a: 1,
  b: {
   
    c: 2
  }
}

// 浅拷贝
let shallowCopy = Object.assign({
   }, obj) 

// 深拷贝
let deepCopy = JSON.parse(JSON.stringify(obj))

obj.b.c = 3
console.log(shallowCopy.b.c) // 3
console.log(deepCopy.b.c) // 2

如何实现

在 JavaScript 中,拷贝操作用于复制对象或数组的值,以便在不影响原始对象的情况下进行操作。拷贝分为深拷贝和浅拷贝两种类型。

浅拷贝(Shallow Copy):

常见的浅拷贝方式包括:

  1. 扩展操作符(Spread Operator):
    使用 ... 操作符进行浅拷贝。

    const originalArray = [1, 2, 3];
    const shallowCopy = [...originalArray];
    
  2. Object.assign() 方法:
    使用 Object.assign() 方法将属性从一个或多个源对象复制到目标对象。

    const originalObj = {
          a: 1, b: 2 };
    const shallowCopy = Object.assign({
         }, originalObj);
    

深拷贝(Deep Copy):

深拷贝创建了一个新对象,并递归地复制原始对象的所有属性及其嵌套属性,确保每个引用类型都是独立的新对象,不会与原始对象共享。

常见的深拷贝方式包括:

  1. 使用递归:
    递归遍历对象的所有属性,并在遇到引用类型时继续递归。

    function deepCopy(obj) {
         
      if (typeof obj !== 'object' || obj === null) {
         
        return obj;
      }
    
      const copy = Array.isArray(obj) ? [] : {
         };
      for (const key in obj) {
         
        if (obj.hasOwnProperty(key)) {
         
          copy[key] = deepCopy(obj[key]);
        }
      }
      return copy;
    }
    
  2. JSON 序列化与反序列化:
    通过先将对象转换为 JSON 字符串,然后再将其解析回对象,实现深拷贝。但这种方法有一些限制,不能复制函数、正则表达式等。

    const originalObj = {
          a: 1, nested: {
          b: 2 } };
    const deepCopy = JSON.parse(JSON.stringify(originalObj));
    

    需要注意什么问题

    在使用拷贝操作时,有一些重要的注意事项需要考虑,特别是在处理复杂的对象和数据结构时。以下是需要注意的几点:

  3. 引用类型:
    拷贝操作通常在处理引用类型(如对象和数组)时更为复杂。浅拷贝可能只复制引用,而深拷贝可能导致性能问题。理解被拷贝对象中的引用关系是很重要的。

  4. 循环引用:
    如果要拷贝的对象中存在循环引用(即对象 A 引用了对象 B,而对象 B 又引用了对象 A),那么简单的拷贝操作可能会导致无限递归或栈溢出。在实现深拷贝时,需要考虑如何处理循环引用。

  5. 性能考虑:
    深拷贝可能在处理大型对象或嵌套深度很深的结构时变得很慢,因为它需要递归地复制每个属性。在这些情况下,可能需要选择性地使用浅拷贝或者其他优化方法。

  6. 不可拷贝属性:
    一些对象的属性是不可枚举或不可拷贝的(例如原型链上的属性)。在拷贝操作中,这些属性可能被忽略。

  7. 函数和特殊对象:
    函数和一些特殊的对象(如正则表达式、Date 对象等)可能需要特殊的处理,特别是在使用深拷贝时。这些对象可能无法通过 JSON 序列化来实现深拷贝。

  8. 性能和内存开销:
    拷贝操作可能导致性能问题和额外的内存开销,特别是在处理大数据结构时。在做出选择时,需要权衡性能和内存使用。

可以考虑使用成熟的第三方库,如 lodash 的 .clone、.cloneDeep 方法,它们在处理拷贝时已经考虑了很多复杂情况。

目录
相关文章
|
2月前
|
JavaScript 前端开发
js实现数据的双向绑定
js实现数据的双向绑定
30 2
|
2月前
|
JavaScript 算法 前端开发
采招网JS逆向:基于AES解密网络数据
采招网JS逆向:基于AES解密网络数据
42 0
|
13天前
|
JavaScript 前端开发 安全
js逆向实战之烯牛数据请求参数加密和返回数据解密
【9月更文挑战第20天】在JavaScript逆向工程中,处理烯牛数据的请求参数加密和返回数据解密颇具挑战。本文详细分析了这一过程,包括网络请求监测、代码分析、加密算法推测及解密逻辑研究,并提供了实战步骤,如确定加密入口点、逆向分析算法及模拟加密解密过程。此外,还强调了法律合规性和安全性的重要性,帮助读者合法且安全地进行逆向工程。
57 11
|
10天前
|
JSON JavaScript 数据格式
手写JS实现深拷贝函数
本文介绍了如何实现一个深拷贝函数`deepClone`,该函数可以处理对象和数组的深拷贝,确保拷贝后的对象与原始对象在内存中互不干扰。通过递归处理对象的键值对和数组的元素,实现了深度复制,同时保留了函数类型的值和基础类型的值。
15 3
|
8天前
|
JSON JavaScript 前端开发
6-19|Python数据传到JS的方法
6-19|Python数据传到JS的方法
|
2月前
|
JSON JavaScript 数据格式
js实现更新数据
js实现更新数据
44 1
|
2月前
|
前端开发 JavaScript 安全
JavaScript——数字超过精度导致数据有误
JavaScript——数字超过精度导致数据有误
34 2
|
2月前
|
JavaScript 前端开发
JavaScript中通过按回车键进行数据的录入
这篇文章提供了一个JavaScript示例代码,演示了如何通过监听回车键(keyCode为13)在网页上实现数据的录入和触发一个警告框提示"正在登录验证......"。
JavaScript中通过按回车键进行数据的录入
|
2月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
36 2
|
2月前
|
JavaScript 算法 数据安全/隐私保护
烯牛数据JS逆向:MD5数据加密?不存在的!
烯牛数据JS逆向:MD5数据加密?不存在的!
62 1