迹忆客 专注技术分享

当前位置:主页 > 学无止境 > WEB前端 > JavaScript >

JavaScript 中的深度复制数组

作者:迹忆客 最近更新:2023/06/05 浏览次数:

在本文中,您将学习深拷贝和浅拷贝的概念。 本文还将介绍在 JavaScript 中对数组执行深拷贝的方法。


JavaScript浅拷贝和深拷贝介绍

在 JavaScript 中,可以通过两种方式复制对象。 它们是深拷贝和浅拷贝。

首先,让我们讨论一下浅拷贝。 对象的浅表副本具有指向与源对象的属性相同的引用的属性。

此处,源对象是从中创建副本的对象。 由于该对象及其浅表副本共享相同的引用,因此对其中一个所做的更改将反映在另一个对象中。

让我们通过一个例子来理解它。

考虑一个对象 student1,其属性名为 name,值为 kevin。 接下来,创建另一个变量 student2,并为其赋值 student2。

let student1 = {
  name: "kevin"
}

let student2 = student1

在这里,我们只是做了一个 student1 对象的浅拷贝。 现在,让我们尝试将 name 属性的值更改为 student2 对象中的其他值。

例如,新值是 john。 当我们打印对象 student1 和 student2 时,值是相同的:john。

示例代码:

let student1 = {
  name: "kevin"
}

let student2 = student1

 student2.name = "john"

console.log(student1)
console.log(student2)

输出:

{
  name: "john"
}
{
  name: "john"
}

这就是对象的浅表副本的行为方式。 它可以更改源对象的属性,因为两个对象共享相同的引用。

然而,对象的深拷贝恰恰相反。 由于副本和源对象不指向相同的引用,因此更改对象的一个属性不会更改其他对象。

在下面的部分中,您将了解深层复制以及在 JavaScript 中实现它的方法。


使用 structuredClone() 方法在 JavaScript 中创建对象的深层副本

在 JavaScript 中创建对象的深拷贝的方法之一是使用 structuredClone() 方法。 该方法使用深度克隆对象的结构化克隆算法。

该方法将要克隆的对象作为参数。 让我们执行克隆。

例如,考虑上面的 student1 对象,它包含 name 属性的值 kevin。 接下来,使用 structuredClone() 方法并提供 student1 对象作为其参数。

最后,将该方法分配给变量 student2。 这使得 student2 对象成为 student1 对象的深拷贝。

接下来,将 student2 对象的属性更改为 john。

这次当您打印两个对象时,它们的属性值不同。 student1 对象的值为 kevin,而 student2 的名称属性为 john。

示例代码:

let student1 = {
  name: "kevin",

}

let student2 = structuredClone(student1)

student2.name = "john"

console.log(student1)
console.log(student2)

输出:

{
  name: "kevin"
}
{
  name: "john"
}

这就是我们如何使用 structuredClone() 方法在 JavaScript 中执行深层复制。


使用 JSON.parse() 和 JSON.stringify() 方法在 JavaScript 中创建对象的深拷贝

我们还可以使用 JSON.parse()JSON.stringify() 方法创建对象的深拷贝。 JSON.stringify() 方法将对象或值转换为字符串,而 JSON.parse() 方法通过解析 JSON 字符串来创建对象或值。

首先,我们可以使用 JSON.stringify() 方法将对象转换为字符串,然后我们可以使用 JSON.parse() 方法通过解析对象来创建对象的深拷贝。

例如,考虑同一个 student1 对象并使用 JSON.stringify() 方法将该对象转换为字符串。 然后,对结果使用 JSON.parse() 方法。

将表达式分配给变量 student2。 接下来,像上面那样更改第一个对象的属性并打印两个对象。

示例代码:

let student1 = {
  name: "kevin",

}


let student2 = JSON.parse(JSON.stringify(student1))

student2.name = "john"

console.log(student1)
console.log(student2)

输出:

{
  name: "kevin"
}
{
  name: "john"
}

我们可以看到这两个对象的属性值是不同的,也就是说我们创建了源对象的深拷贝。 因此,我们可以使用 JSON.parse()JSON.stringify() 方法在 JavaScript 中执行对象的深拷贝。

但是,我们在使用函数和对象时会遇到问题。 让我们实现一个包含函数和 Date() 对象的对象的深度克隆,以更清楚地了解问题。

将新字段添加到 student1 对象,如下例所示。

示例代码:

let student1 = {
  name: "kevin",
  age: function(){
        return 24;
  },
  enrolledDate: new Date()

}

接下来,使用 JSON.parse()JSON.stringify() 函数创建上述对象的深层副本。 然后,更改第一个对象的名称属性。 最后,打印两个对象。

示例代码:

let student2 = JSON.parse(JSON.stringify(student1))
student2.name = "john"

console.log(student1)
console.log(student2)

输出:

{
  name: 'kevin',
  age: [Function: age],
  enrolledDate: 2023-01-19T16:15:30.914Z
}
{ name: 'john', enrolledDate: '2023-01-19T16:15:30.914Z' }

在这里,我们可以在对象的深拷贝中看到一些值得注意的问题。 第一个问题是该函数缺少克隆对象。

另一个问题是嵌套对象new Date() 的类型发生了变化。 克隆后,新的 Date() 对象变为 String 类型。 您可以注意到日期前后的引号。

因此,我们在使用 JSON.parse()JSON.stringify() 方法对包含函数和类型的对象进行深拷贝时发现了一个问题。 我们将在本文的下一节中解决该问题。


使用 Lodash 库在 JavaScript 中创建对象的深拷贝

我们可以在使用 lodash 库克隆函数和嵌套对象时解决这个问题。 lodash 提供了一个方法 cloneDeep(),它以源对象为参数,对其进行深度克隆。

您可以使用以下命令安装库。

npm i -g lodash

例如,在代码顶部要求库。 将其分配给常量 _

使用常量调用 cloneDeep(),其中 student1 对象是参数。 像以前一样更改对象属性的值。 最后,打印两个对象。

示例代码:

const _=require('lodash')
let student1 = {
  name: "kevin",
  age: function() {
    return 24;
  },
  enrolledDate: new Date()

}


let student2 = _.cloneDeep(student1)

student2.name = "john"

console.log(student1)
console.log(student2)

输出:

{
  name: 'kevin',
  age: [Function: age],
  enrolledDate: 2023-01-23T15:02:56.059Z
}
{
  name: 'john',
  age: [Function: age],
  enrolledDate: 2023-01-23T15:02:56.059Z
}

最后,我们可以深度克隆对象并且仍然拥有函数和嵌套对象。 因此,我们可以使用 lodash 库在 JavaScript 中创建对象的深度克隆。

上一篇:在 JavaScript 中将毫秒转换为日期

下一篇:没有了

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 JavaScript 中将数组转换为不带逗号的字符串

发布时间:2023/03/09 浏览次数:175 分类:JavaScript

JavaScript 允许终止数组的分隔符并使用其方法 join() 将其转换为纯行字符串。可以有多种其他方法将数组转换为字符串,但对于忽略逗号或任何其他分隔符,join() 方法是绝对的。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便