通过引用传递和传递的值及其在 JavaScript 中的修改。
脚本对象引用及其副本
在处理 JavaScript 时,您将面临与 JavaScript 如何处理其基元变量和非基元变量以及何时用作值或用作引用相关的混淆。使用值时,每种方法的工作方式都不同。
今天,我们将讨论JavaScript如何定义其引用和对象,以及它将如何在不同的场合处理它们。
类型
让我们从基础开始,有2种类型的JavaScript对象,即原始和非原始对象。基元类型包括字符串、数字、空、布尔型、BigInt、符号(新引入的)和未定义的。
另一方面,非基元类型是存储中的引用,因为它们没有定义的存储。非基元类型可以在存储中变大,这就是为什么JS最好地将其视为也称为对象的引用。每个对象都是从 G小叶对象类派生而来的。
每个对象都有一个分配的标识符,该标识符保存其引用的值,就像常规变量标识符也具有其作用域和Unicode一样。
更新基元类型
让我们从基元类型开始并更新它们。我们将首先创建一个字符串变量并将其分配给另一个变量,然后更新新变量并比较输出。
基元类型示例
以下程序的输出将是唯一的,并指出每个基元值将保存在另一个内存地址中:
Output - test another test
更新非基元类型
当我们使用非基元类型时,期望是不同的。我们将执行与上述相同的操作,但不是更新值,而是更新内部的属性。
非基元类型示例
在这种情况下,输出将更新原始对象,因为它们指向相同的位置:
Output - { name: 'another test' }
我们可以通过使用来克隆对象,并且值将有所不同。例如Object.assign
使用对象分配
在这种情况下,输出将不同,结果将打印原始对象,因为它们指向不同的内存地址:
Output - { name: 'test' }
如果我们嵌套了非原始属性呢?
我们正在尝试的示例将属性指向基元类型,但如果任何一个属性是非基元的呢?
让我们看看预期的场景,我们将在对象内再创建一个非原始属性,并将尝试更新最新的对象并将其与现有对象进行比较:
对嵌套对象使用对象分配
该程序的输出将是:
Output - { name: 'test', properties: { location: 'location two' } }
现在,这是一件有趣的事情,属性是原始的,因此具有不同的位置,但是是非原始的,并且与 共享相同的地址,并且在更新时也会更新嵌套对象。这是因为只在顶级创建属性,而不执行嵌套克隆。namepropertiesobj.propertiesObject.assign
对于嵌套克隆,有一些方法,例如 。structuredClone(node v17), recursive methods, JSON.parse(JSON.stringify(obj))and third party library
将变量传递给函数
当我们处理函数并传递值时,有两种方式按值传递变量或按引用传递变量。首先,让我们了解JavaScript将如何定义将变量传递给函数时要执行的操作。
按值传递与按引用传递
在JavaScript中,它从不显式比较类型是值还是引用,但是当我们调用具有很少参数的方法时,会发生一个简单的机制。脚本将创建输入的副本。
由于我们创建的每个函数都是 Function 类的导数,因此每个函数都有一个称为数组的属性,并分发给该方法。在此处阅读有关参数的更多信息。arguments
因为参数是非首字母类型。JavaScript 使用 rest 是作为数组传递的参数,当函数内的任何变量更新时,它是一个参数关键字进行更新。Object.assign(arguments, [...rest])
由于我们创建了一个新的 Argument 实例,如果值是基元的,它将为非基元创建一个新地址,它将指向相同的实例变量。
传递基元类型
现在,我们知道函数将创建一个新变量,因此传递基元类型似乎没有任何问题,并且变量将保持其原始状态。
将值传递给方法的基元示例
以下程序的输出将是其原始状态,无需修改:
Output - test
传递非基元类型并更新其引用
当传递非基元类型时,它还会创建一个副本,并且将引用该值。但是当更新引用时,它现在将指向另一个变量,因为我们向它提供了一个副本,而不是一个实际的对象。
将值传递给方法的非基元示例
以下程序的输出仍将处于其原始状态,无需进行任何修改,因为我们更新了引用本身:
Output - { name: 'test' }
传递非基元类型并更新其属性
按照上面的示例,如果我们更新引用,那么它将指向一个新的内存地址,但是如果我们更新属性,那么它将更新值。
将非基元值传递给方法和更新属性的示例
以下程序的输出将不会处于其原始状态,并且 name 属性将分配一个新值,因为引用不会使用相同的标识符进行修改和更新。
Output - { name: 'another test' }
结论
JavaScript是一种令人惊讶的语言,当在深层次上使用时,它的所有实现都有其调整。最复杂的情况是,当我们处理一个嵌套对象时,每个对象都有自己唯一的共享标识符。因此,建议使用所需的引用,并始终创建具有属性的嵌套对象以避免冲突。Object.assign