JavaScript深拷贝与浅拷贝实现详解

yizhihongxing

JavaScript深拷贝与浅拷贝实现详解

什么是拷贝?

在JavaScript中,我们经常需要将对象或者数组进行复制操作,这被称为拷贝。在拷贝过程中,我们需要注意两个概念:浅拷贝和深拷贝。

什么是浅拷贝?

浅拷贝仅仅是复制了对象或数组的引用,而并没有克隆对象或数组。也就是说,对于被拷贝的对象或数组,它们的属性仍然指向原对象或数组中的属性。浅拷贝通常使用的方法有:

Object.assign方法

const obj = {a: 1, b: 2};
const copy = Object.assign({}, obj);
console.log(copy); // {a: 1, b: 2}

扩展运算符(...)

const obj = {a: 1, b: 2};
const copy = {...obj};
console.log(copy); // {a: 1, b: 2}

需要注意的是,浅拷贝只能复制对象或数组的一层属性,如果被拷贝的对象或数组中还有嵌套的对象或数组,浅拷贝并不会进行递归拷贝。

什么是深拷贝?

深拷贝则是完全复制了对象或数组,包括对象或数组中的所有嵌套对象或数组,新的对象或数组和原对象或数组完全独立无关。深拷贝通常使用的方法有:

JSON.parse和JSON.stringify方法

const obj = {a: 1, b: {c: 2}};
const copy = JSON.parse(JSON.stringify(obj));
console.log(copy); // {a: 1, b: {c: 2}}

需要注意的是,因为JSON.stringify方法无法处理Symbol、Date、函数等特殊类型,因此在深拷贝过程中这些类型会被忽略掉。

递归拷贝

function deepCopy(obj) {
  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  } else if (typeof obj === 'object' && obj !== null) {
    const copy = {};
    Object.keys(obj).forEach((key) => {
      copy[key] = deepCopy(obj[key]);
    });
    return copy;
  } else {
    return obj;
  }
}

const obj = {a: 1, b: {c: 2}};
const copy = deepCopy(obj);
console.log(copy); // {a: 1, b: {c: 2}}

递归拷贝可以完美地复制对象或数组中的所有属性,除了Symbol、Date、函数等特殊类型。

示例说明

示例一

const obj = {
  a: 1,
  b: {
    c: 2
  }
};
const copy1 = Object.assign({}, obj);
const copy2 = {...obj};
const copy3 = JSON.parse(JSON.stringify(obj));
const copy4 = deepCopy(obj);

obj.b.c = 3;

console.log(copy1); // {a: 1, b: {c: 3}}
console.log(copy2); // {a: 1, b: {c: 3}}
console.log(copy3); // {a: 1, b: {c: 2}}
console.log(copy4); // {a: 1, b: {c: 2}}

在这个示例中,我们首先定义了一个对象obj,其中包含一个嵌套对象b。然后我们使用了四种方法分别对obj进行了浅拷贝和深拷贝。接着,我们修改了obj.b.c的值为3,然后输出了四个拷贝的结果。可以看到,浅拷贝的两种方法都会随着原对象的改变而发生改变,而深拷贝的两种方法则不受原对象的影响。

示例二

const arr = [1, 2, [3, 4]];
const copy1 = arr.slice();
const copy2 = [...arr];
const copy3 = JSON.parse(JSON.stringify(arr));
const copy4 = deepCopy(arr);

arr[2][0] = 5;

console.log(copy1); // [1, 2, [5, 4]]
console.log(copy2); // [1, 2, [5, 4]]
console.log(copy3); // [1, 2, [3, 4]]
console.log(copy4); // [1, 2, [3, 4]]

在这个示例中,我们首先定义了一个数组arr,其中包含一个嵌套数组。然后我们使用了四种方法分别对arr进行了浅拷贝和深拷贝。接着,我们修改了arr[2][0]的值为5,然后输出了四个拷贝的结果。可以看到,浅拷贝的两种方法都会随着原数组的改变而发生改变,而深拷贝的两种方法则不受原数组的影响。

总结

浅拷贝和深拷贝是JavaScript中常用的拷贝方式,每种方式都有其优缺点。在实际应用中,我们需要根据具体的情况选择合适的拷贝方式,以保证拷贝的结果符合预期。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript深拷贝与浅拷贝实现详解 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • Javascript Date setMilliseconds() 方法

    JavaScript 中的 setMilliseconds() 方法用于设置日期对象的毫秒部分。在本教程中,我们将详细介绍 setMilliseconds() 方法的使用方法。 setMilliseconds() 方法基本语法如下: date.setMilliseconds(msValue) 其中,msValue 是设置的毫秒值,必须是一个介于 0 到 99…

    JavaScript 2023年5月11日
    00
  • 一个简易时钟效果js实现代码

    下面我将为您详细讲解实现一个简易时钟效果的JavaScript代码。 实现步骤 1. HTML代码 首先,在页面中需要有一个DOM元素用来显示时钟,如下所示: <div id="clock"></div> 2. CSS代码 通过CSS样式调整时钟的外观,如下所示: #clock { width: 150px; he…

    JavaScript 2023年5月27日
    00
  • 时间戳转换为时间 年月日时间的JS函数

    时间戳是一种在计算机中通用的时间表示方式。它表示的是一个自1970年1月1日0时0分0秒以来经过的毫秒数。在JavaScript中,时间戳以整数的形式存在,我们可以通过一些函数将其转换成人类易读的日期时间格式。 以下是一个将时间戳转换为具有年月日时间格式的JavaScript函数的完整攻略: 步骤1:获取时间戳 首先,我们需要在JavaScript中获取一些…

    JavaScript 2023年5月27日
    00
  • 介绍一下sourcemap

    Sourcemap(源代码映射)用于将生产环境中的压缩代码映射回原始的源代码。在前端开发过程中,JavaScript、CSS 和其他文件通常会被压缩和混淆,以减小文件大小和提高网站加载速度。然而,这会让调试和错误定位变得困难,因为生产环境中的代码难以阅读和理解。 Sourcemap 的作用是在开发和生产环境之间建立一个桥梁,使开发人员能够在浏览器中查看、调试…

    JavaScript 2023年4月17日
    00
  • JavaScript Date对象使用总结

    JavaScript Date对象使用总结 Date对象是 JavaScript 中处理日期和时间的核心对象之一。它可以用来表示特定的时刻,以及对这些时刻进行各种计算和操作。本文就对 Date 对象进行详细讲解,包括 Date 对象的构造函数、常用的方法和属性,以及一些在实践中遇到的问题。 Date对象的构造函数 Date 对象的构造函数有多种形式。最常用的…

    JavaScript 2023年5月27日
    00
  • 有趣的JavaScript数组长度问题代码说明

    下面我会详细讲解“有趣的JavaScript数组长度问题代码说明”的完整攻略,包含以下内容: 核心概念:JavaScript数组的length属性 思路分析:通过操作length属性实现数组元素的删除与插入 代码示例1:删除数组元素的常规方法和length属性的应用 代码示例2:插入数组元素的常规方法和length属性的应用 1. 核心概念:JavaScri…

    JavaScript 2023年5月27日
    00
  • JavaScript学习小结(7)之JS RegExp

    JavaScript学习小结(7)之JS RegExp 简介 RegExp是JavaScript中的一个正则表达式对象,用于匹配字符串中的对应字符序列。使用正则表达式可以轻松地检索符合特定模式的字符串,同时也可以将文本内容替换为不同的字符。 创建RegExp对象 有两种创建RegExp对象的方法:字面量和构造函数。 字面量创建RegExp对象 使用字面量创建…

    JavaScript 2023年6月10日
    00
  • 使用JavaScript开发跨平台的桌面应用详解

    使用JavaScript开发跨平台的桌面应用详解 要使用JavaScript开发跨平台的桌面应用,可以使用Electron框架。Electron可以让开发者使用HTML、CSS和JavaScript构建桌面应用程序,并且能够在Windows、macOS和Linux等不同平台上运行。 以下是使用Electron来开发跨平台的桌面应用的步骤: 1. 安装Elec…

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