【问题标题】:Using Javascript slice updates old values [duplicate]使用 Javascript 切片更新旧值 [重复]
【发布时间】:2017-12-30 16:51:34
【问题描述】:

我正在尝试编写一个函数,该函数从多维数组 (myArray) 中选择一个随机条目,将其保存到一个新变量 (myTempArray) 并使用 id 号 (计数器) 更新第一个条目。

当我更改 mytempArray[0][0][0] 的值时,它也会更新 myArray 中的等效值。我不希望这些值改变。

如何阻止这种情况发生?切片是错误的使用方法吗?如果是这样,我如何复制原始数组条目以便我可以修改它并在其他地方使用?代码如下:

var myArray = [
[[0, "Description 1", 0, 0, 1, 6, 0, 0, 0, true, 0]],
[[0, "Description 2", 0, 0, 1, 6, 0, 0, 0, true, 0]],
[[0, "Description 3", 0, 0, 1, 6, 0, 0, 0, true, 0]],
];

function randomNumber (min, max) {
return Math.floor((Math.random() * max) + min);
};

counter = 1;

function myfunction(){

myrand = randomNumber(0,myArray.length-1); 
mytempArray = myArray.slice(myrand,myrand+1);
mytempArray[0][0][0] = counter;
counter++;
};

myfunction();

【问题讨论】:

  • 数组是引用类型。 slice 只做一个浅克隆,嵌套数组通过引用复制到新的。
  • 查看这里了解如何深度复制数组。 stackoverflow.com/questions/597588/…
  • 除了Object.assign(),您还可以使用...[] 扩展运算符。
  • @ThirueswaranRajagopalan:传播和休息都是语法,而不是运算符。
  • @ThirueswaranRajagopalan ...而且没有人做深度克隆。

标签: javascript arrays


【解决方案1】:

请记住,slice 仅适用于结构中的一个级别。如果你想要一个副本,你必须自己实现。

function myfunction() {
    var myrand = randomNumber(0, myArray.length - 1);
    var mytempArray = myArray.slice(myrand, myrand + 1); // <== Only copies one level
    mytempArray[0] = mytempArray[0].slice();             // <== Copy the next
    mytempArray[0][0] = mytempArray[0][0].slice();       // <== And the next
    mytempArray[0][0][0] = counter;
    // Presumably do something with `mytempArray` or return it
    counter++;
}

请参阅下文,了解我在其中所做的其他一些更改。


一些旁注:

  • 除非您在未显示的地方声明myrandmytempArray,否则您的代码将成为The Horror of Implicit Globals* 的牺牲品。请务必声明您的变量。
  • 函数声明(相对于函数表达式)的末尾不需要;; 是语句终止符。声明不是陈述。

* (这是我贫血的小博客上的帖子)

【讨论】:

  • 假设数据是有效的JSON,var deepCopy = JSON.parse(JSON.stringify(oldArray));.
  • @JaredSmith:我坚信使用stringify+parse 复制数据在几个层面上都是错误的。 :-)
  • 嗯,通用的替代方法是递归地复制数据结构。在 JavaScript 中,这意味着要么蹦床要么保持显式堆栈以避免内存不足。或者,您可以为特定数据结构编写一百万个一次性版本,其中包含所有重复和潜在的错误。我不认为它会是“正确的”,无论你用哪种方式切割它(双关语)。
  • 感谢@T.J.Crowder 的成功!
猜你喜欢
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多