为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在JavaScript中对数组“B”的更改会传播到数组“A”?

为什么在JavaScript中对数组“B”的更改会传播到数组“A”?

慕容森 2022-09-16 20:59:32
我创建了一个名为“alphabet”的常量,并将其分配给包含字母表前 5 个字母的数组。然后,我想要一个函数,该函数将向数组中的每个字符添加一个数字,以枚举它们。但是,我不希望修改原始“字母表”数组中的值,因此我在枚举函数中创建了一个“temp”变量,并且只对其进行了更改。但是,我对“temp”所做的任何更改都扩展到“字母表”。我不明白为什么,我想阻止这种情况发生。const alphabet = ["a", "b", "c", "d", "e"];function alphaPosition(seq) {  //'temp' gets 'seq' to avoid making changes directly on the provided argument.  let temp = seq;  //adds indexes to each element in the 'temp' array:  for (let i = 1; i <= temp.length; i++) {    temp[i - 1] = temp[i - 1] + i;  }  return temp;}console.log(  "Step 1. 'alphabet' array before running the 'alphaPosition' function:");console.log(alphabet);console.log(  "Step 2. This is the final value of 'temp' in 'alphaPosition' after running the function. An index has been added to every element in the array, as expected:");console.log(alphaPosition(alphabet));console.log(  "Step 3. Here's the 'alphabet' array after running 'alphaPosition'. Indexes have also been added to every element, despite not modifying the function argument directly:");console.log(alphabet);输出:/*-> Step 1. 'alphabet' array before running the 'alphaPosition' function:-> ["a", "b", "c", "d", "e"]-> Step 2. This is the final value of 'temp' in 'alphaPosition' after running the function. An index has been added to every element in the array, as expected:-> ["a1", "b2", "c3", "d4", "e5"]-> Step 3. Here's the 'alphabet' array after running 'alphaPosition'. Indexes have also been added to every element, despite not modifying the function argument directly:-> ["a1", "b2", "c3", "d4", "e5"]*/为什么对“临时”的更改会传播为“字母表”?我希望,既然我把“字母表”定义为一个常量,那么甚至不应该修改它。此外,我从不在函数中对其进行更改。我只用它来定义“温度”。有没有办法防止这些传播的发生?为什么使用中间变量来避免对原始数字进行更改,而不是数组?如果对此有任何帮助或澄清,我将不胜感激。我已经将我的代码添加到这个CodePen中,以防你想调整它或尝试更多。提前感谢您的任何帮助。
查看完整描述

2 回答

?
DIEA

TA贡献1820条经验 获得超2个赞

这是关于分配在脚本中的工作方式。给定以下代码:


const a = { foo: "bar" };

const b = a;

变量和两者都指向同一对象。这意味着内存中只有一个对象,当您尝试使用对象访问对象时,将反映对象指向的可变,反之亦然。例如:abab


const a = { foo: "bar" };

const b = a;


a.foo = "baz";


console.log(a);

console.log(b);

展开代码段

那么现在,我们如何使这种情况不会发生呢?为此,我们可以将 的浅副本分配给 。这可以通过几种不同的方式完成,下面使用传播运算符(...):ab


const a = { foo: "bar" };

const b = { ...a };


a.foo = "baz";


console.log(a);

console.log(b);

展开代码段

所以现在,内存中有两个不同的对象。你会注意到我称之为浅层复制,这很重要:如果你有深层对象,你需要深度复制才能完成同样的解耦。


如何在您的特定情况下解决此问题:


针对您的特定情况的 TLDR 是,您的临时变量应该是数组的浅副本,而不是对现有数组的引用:


let temp = [...seq];


查看完整回答
反对 回复 2022-09-16
?
GCT1015

TA贡献1827条经验 获得超4个赞

这似乎是重复的。潜在的答案就在这里

我在下面解释原因:

对于字符串和数字,javascript 似乎是按值传递的,而数组等对象是按引用传递的。

这意味着在你的第一个例子中;该函数正在获取对原始数组的引用,当您这样做时,temp实际上只是一个指向传入的原始对象的指针。在这种情况下,当您修改温度时,情况就是这样;它实际上是在修改字母表。let temp = seqalphabet

按值传递只是将值发送到函数,因此原始变量与数字示例中的变量相同。

为了获得预期的结果,您需要制作数组的深度副本,例如 .let temp = deepCopy(seq)

我认为使用可能只是用户知道不要修改它的语法,一些编辑器不会让你在代码中重新修改const,但在这种情况下,它以迂回的方式发生。const


查看完整回答
反对 回复 2022-09-16
  • 2 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信