在 JavaScript 中复制对象
各种编程语言具有各种数据结构,允许你在内存中组织和存储数据。每个数据结构的工作方式都是独一无二的。例如,在 C++ 和 Java 中,我们有 Hashmap 以键值形式存储数据。同样,在 JavaScript 中,我们有一个称为对象的数据结构,它允许你以键值
格式存储数据。
在访问数据时,这些对象会派上用场。我们可以使用对象的键轻松访问对象中的任何数据。在本文中,我们将看到在 JavaScript 中复制对象的各种方式。
请注意 JavaScript 对象是可变的,并且存储为引用。如果你已经创建了一个对象并希望将其分配给其他某个对象,那么该对象现在将保存该对象的地址。由于我们将对象的引用存储在另一个对象中,然后使用这个新对象,我们可以轻松地更改原始对象中存在的值。
var a = {'name': 'Adam', 'company': 'Google'}
var b = a;
b.name = 'Sam'
console.log(a.name, b.name);
输出:
Sam Sam
从上面的示例中可以看出,将一个对象分配给另一个对象不会复制对象本身。它只会将旧对象的地址存储到新对象中。
在 JavaScript 中有两种复制对象的方法。一种方式称为浅拷贝,另一种方式称为深拷贝。为了实现这些方法,我们可以使用一些 JavaScript 方法,如下所示。
JavaScript 中的浅拷贝对象
在浅拷贝中,只有出现在对象第一层的键值
对才会被复制到新对象中。并且所有嵌套的元素或属性,例如数组或内部的另一个对象,都不会被复制,而是将它们的引用存储在此对象中。
在浅拷贝中,原始对象的一些属性也会受到影响。要理解这一点,请看下面的例子。
var obj1 = {
'firstName': 'James',
'lastName': 'Bond',
'films': ['No Time To Die', 'Spectre', 'Skyfall', 'Quantum of Solace'],
'actors':
{'characters': {'realName': 'Daniel Craig', 'fakeName': 'James Bond'}}
}
在这个例子中,我们有一个名为 obj1
的对象。要使用 JavaScript 对这个对象进行浅拷贝,我们可以使用 Object.assign()
和扩展运算符 ...
。让我们使用 JavaScript 中的以下方法对 obj1
执行浅拷贝。
Object.assign()
方法
Object.assign()
方法有两个参数。第一个参数是复制完成后将返回的 target
对象。第二个参数是我们要复制的对象:obj1
。在我们的例子中,我们将传递一个空对象 {}
作为目标。这是因为 obj1
中的所有元素都将被复制到这个空对象中。复制完成后,Object.assign()
将返回我们将存储在 obj2
变量中的新对象。
var obj2 = Object.assign({}, obj1);
稍后,我们将修改此对象的属性,我们将实际了解为什么将其称为浅拷贝。
obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';
console.log(obj1);
console.log(obj2);
输出:
在这里,我们使用 obj2、firstName
、films[]
数组中的第一部电影和 actors.characters
对象中的 realName
属性更改三个值。然后我们打印这两个对象。
上图显示两个对象中只有 firstName
属性没有更改。另外两个属性 films[]
和 realName
在这两个对象中都发生了变化。这被称为浅拷贝,因为 firstName
属性是唯一的,而其他属性对于两个对象都是通用的,因为我们在这里存储地址。此处,仅复制存在于第一级的属性。
- 展开运算符 (
...
)
rest 运算符将把 obj1
的属性复制到 obj2
中。这类似于 Object.assign()
,我们浅拷贝对象的属性。要使用扩展运算符复制对象,你必须在扩展符号后写入对象名称。
var obj2 = {...obj1};
obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';
你还将获得我们在使用 Object.assign()
方法后获得的相同输出。
深度复制 JavaScript 中的对象
在深度复制中,所有键值
对都将被复制到新对象中。要执行深度复制,我们可以使用 JSON.parse()
和 JSON.stringify()
方法。请注意,深层复制不会复制原型对象中存在的属性。
使用 JSON.stringify()
,我们将首先将整个对象(在本例中为 obj1
)转换为字符串,然后在 JSON.parse()
方法的帮助下,我们将解析将此字符串重新转换为 JSON 格式。
let obj2 = JSON.parse(JSON.stringify(obj1));
在这里,你可以修改 obj2
内的任何属性,这不会影响 obj1
内的属性。
obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';
输出:
我们正在修改之前修改的相同值,现在你可以注意到,当我们更改 obj2
的属性时,它不会影响 obj1
的属性。
相关文章
JavaScript 函数重载
发布时间:2024/03/17 浏览次数:129 分类:JavaScript
-
本教程展示了如何使用 if-else 语句、switch 语句和函数表达式在 JavaScript 中实现函数重载。
JavaScript 中的 history.forward() 函数
发布时间:2024/03/17 浏览次数:195 分类:JavaScript
-
本文将帮助你了解如何使用 JavaScript 浏览浏览器。
JavaScript console.error
发布时间:2024/03/17 浏览次数:61 分类:JavaScript
-
JavaScript 有多个与其他数据类型和对象交互的对象。控制台也是一个类似的对象,它允许我们在浏览器环境中预览开发输出。本文展示了控制台在 JavaScript 中的使用。
Discord JavaScript 控制台
发布时间:2024/03/17 浏览次数:177 分类:JavaScript
-
实验上,通过控制台面板向收件人发送消息是一个有趣的事实。几乎抽象的 UI 在发送和接收消息时几乎没有任何踪迹来了解正在运行的内容。使用标头,添加特定的用户 ID,结合 Disco