详解JS深拷贝与浅拷贝

详解JS深拷贝与浅拷贝

一、什么是拷贝

在JavaScript中,我们经常需要对一个数据进行拷贝,这里的拷贝指的是将一个数据重新复制一份,从而在新的数据上进行操作,而原始数据不会受到影响。拷贝手段分为两种:浅拷贝和深拷贝。

1.1 浅拷贝

浅拷贝就是将原始数据的引用复制一份给新的数据,这样新数据和原始数据指向同一块内存区域,因此对新数据进行操作,也会影响原始数据。

示例代码:

let obj = {a: 1, b: {c: 2}};
let newObj = obj;
newObj.a = 3;
newObj.b.c = 4;
console.log(obj); // {a: 3, b: {c: 4}}

可以看到,对 newObj 进行操作,同时也影响了 obj

1.2 深拷贝

深拷贝是将原始数据完整地复制一份给新的数据,新数据和原始数据没有任何联系,对新数据的操作也不会影响原始数据。

示例代码:

let obj = {a: 1, b: {c: 2}};
let newObj = JSON.parse(JSON.stringify(obj));
newObj.a = 3;
newObj.b.c = 4;
console.log(obj); // {a: 1, b: {c: 2}}
console.log(newObj); // {a: 3, b: {c: 4}}

可以看到,对 newObj 进行操作,并不影响 obj

二、浅拷贝的实现方法

2.1 Object.assign()

Object.assign()方法将所有的可枚举属性的值从一个或多个源对象复制到目标对象。它会先创建一个新对象,然后将源对象的属性拷贝到新对象上。

示例代码:

let obj1 = {a: 1,b: {c: 2}};
let obj2 = Object.assign({}, obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 4}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

2.2 扩展运算符 ...

扩展运算符 ... 也可以实现浅拷贝。它能够将一个数组或对象展开成一系列参数,方便地将其插入一个函数或对象字面量中。

示例代码:

let obj1 = {a: 1,b: {c: 2}};
let obj2 = {...obj1};
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 4}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

三、深拷贝的实现方法

3.1 手写递归函数

手写递归函数可以非常方便地实现深拷贝,它会遍历对象的所有属性和子属性,并将其转化为一个新的对象返回。

示例代码:

function deepClone(obj) {
  let newObj = Array.isArray(obj) ? [] : {};
  if (obj && typeof obj === "object") {
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        newObj[key] = deepClone(obj[key]);
      }
    }
  }
  else {
    newObj = obj;
  }
  return newObj;
}

let obj1 = {a: 1,b: {c: 2}};
let obj2 = deepClone(obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 2}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

3.2 使用第三方包

第三方包 lodash 中的 _.cloneDeep() 方法也可以实现深拷贝。这个方法可以递归地复制一个 JavaScript 对象。

示例代码:

const _ = require('lodash');

let obj1 = {a: 1,b: {c: 2}};
let obj2 = _.cloneDeep(obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 2}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

四、深度递归拷贝的注意事项

在深度递归拷贝中,需要注意以下几点:

  1. 对 Date、RegExp、Function 等对象无法进行深拷贝,需要特殊处理。
  2. 对于对象的循环引用,需要避免死循环。

五、总结

浅拷贝只是复制了一个对象的引用,而深拷贝则是复制了整个对象。使用递归函数实现深拷贝时,需要考虑到各种对象类型的情况。如果对数据的操作需要保证原始数据的不变性,建议使用深拷贝。

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

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

相关文章

  • javascript实现简单打字游戏

    下面我将详细讲解JavaScript实现简单打字游戏的完整攻略。 思路 我们可以通过JavaScript来实现简单的打字游戏。具体而言,我们可以按照以下思路来实现: 首先,我们需要准备一些字符串,这些字符串将作为打字游戏的关键词。这些字符串可以存在一个数组里。 接下来,我们需要一个计时器,用来计算打字游戏进行的时间,同时,计算玩家最后得分。这里我们可以使用s…

    JavaScript 2023年5月28日
    00
  • JS实现数组去重方法总结(六种方法)

    这里是JS实现数组去重方法总结(六种方法)的完整攻略。 一、方法一:利用ES6 Set特性去重 利用ES6新特性Set(集合)的特性,可以很方便地去重。 实现方法如下: let arr = [1, 2, 3, 4, 1]; let newArr = […new Set(arr)]; console.log(newArr); // [1, 2, 3, 4]…

    JavaScript 2023年5月27日
    00
  • 一个即时表单验证的javascript代码

    下面就为您详细讲解如何编写一个即时表单验证的 JavaScript 代码。 编写 JavaScript 表单验证代码的基本步骤 获取表单的各个输入项,如输入框、单选框、多选框等,并对每个输入项都定义一个监听事件(如 onblur、onkeyup 等),监听输入内容的改变。 在监听事件中编写检验函数,该函数应当返回布尔值来表示输入项是否符合要求。可以根据不同的…

    JavaScript 2023年6月10日
    00
  • JavaScript实现字符雨效果

    JavaScript实现字符雨效果 在网页上实现字符雨效果,可以通过在HTML的body元素中添加一个全屏的canvas元素,然后使用JavaScript编写一个动画效果,不断更新canvas中的字符颜色和位置,从而实现字符雨效果。 准备工作 在HTML中添加一个全屏的canvas元素 <canvas id="matrix-canvas&qu…

    JavaScript 2023年5月28日
    00
  • JavaScript获取function所有参数名的方法

    下面我将详细讲解“JavaScript获取function所有参数名的方法”的完整攻略。 1. 使用Function.prototype.toString() 我们可以通过 Function.prototype.toString() 方法来获取函数的字符串表示形式,然后从该字符串中解析出函数的参数名。具体做法如下: function getParamName…

    JavaScript 2023年5月27日
    00
  • 详解如何在JavaScript中使用for循环

    以下是“详解如何在JavaScript中使用for循环”的完整攻略。 1. for循环简介 for循环是一种在JavaScript中常用的循环结构,也是最基本的三种循环结构之一。for循环支持设置循环条件、循环执行语句和循环计数器的初始值,用于重复执行相同的代码块。 一般来说,for循环的语法结构如下: for (initialization; condit…

    JavaScript 2023年5月28日
    00
  • JavaScript每天必学之数组和对象部分

    JavaScript每天必学之数组和对象部分 一、数组 数组是一种特殊的变量,它可以存储多个数据项,并且这些数据项可以是任意不同的数据类型。在 JavaScript 中,数组属于对象类型,但与其他对象不同的是,它可以通过索引来访问数组中的元素。 1.创建数组 JavaScript 中创建数组有两种方式,一种是使用数组字面量,另一种是通过 Array 构造函数…

    JavaScript 2023年5月27日
    00
  • JS关于刷新页面的相关总结

    JS关于刷新页面的相关总结 在前端开发中,页面刷新是一项非常重要的操作。在JavaScript中,可以通过不同的方式来实现页面的刷新,本篇文章将对JS关于刷新页面的相关知识进行总结。 1. location.reload() location.reload() 方法用于重新加载当前文档。该方法会重新向服务器发送请求,从而获取最新的内容,刷新页面。下面是一个简…

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