函数调用如何影响先前的操作? [重复]

问题描述 投票:0回答:2

这个问题在这里已有答案:

我在JavaScript遇到了一些完全违背我的直觉的东西。我首先定义一个函数Shuffle(Input_array),它使数组的顺序随机化。然后我定义一个数组,Words,将其打印到控制台,然后从Shuffle(Words)打印结果。

这是代码:

<script>
function Shuffle(Input_array) {
  var currentIndex = Input_array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = Input_array[currentIndex];
    Input_array[currentIndex] = Input_array[randomIndex];
    Input_array[randomIndex] = temporaryValue;
  }
  return Input_array;
}

var Words = [["I","think"],["this","is"],["very","strange"]];
console.log(Words);
console.log(Shuffle(Words));
</script>

运行此脚本时,我的两个调用都会生成相同的输出,即一个混洗数组。但是,在注释掉最后一个console.log命令时,数组按照我定义的顺序打印。

这怎么可能?似乎第一个console.logoutput在第二个中发生的任何事情都会受到影响。

应该注意的是,如果我以一维方式定义我的数组,例如var Words = ["This", "actually", "works"];,则不会发生这种情况。我不知道我的函数是否以某种方式无法处理2D数组,但这根本不重要,因为后来的函数调用不应该影响它之前的操作。

javascript
2个回答
4
投票

Javascript控制台包含数组的实时副本,而不是调用console.log()时内容的快照。 Shuffle()函数修改了数组。如果在调用Shuffle()后展开数组的第一个日志的内容,它将显示当前内容,这些内容按随机顺序排列。

使用1D数组不会发生这种情况的原因是因为console.log()会立即显示内容,而不是等待您单击显示三角形。

如果在两个调用之间设置断点,则可以查看数组的原始未抽取内容。或者您可以使用console.log(JSON.stringify(Words))以文本格式查看快照。


1
投票

它正在按预期工作,因为您正在修改输入数组。在Javascript中,所有对象都在内存中有引用,如果您在不事先创建对象的新实例的情况下修改它,则会更改“原始”对象。

并且数组基本上是对象,因此应用相同的原则。

要修复shuffle方法,您需要创建一个新实例,而不是直接操作输入数组。

function Shuffle(Input_array) {
  Input_array = Input_array.slice(); // creates a new instance in memory
  var currentIndex = Input_array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = Input_array[currentIndex];
    Input_array[currentIndex] = Input_array[randomIndex];
    Input_array[randomIndex] = temporaryValue;
  }
  return Input_array;
}

var Words = [["I","think"],["this","is"],["very","strange"]];
console.log(Words);
console.log(Shuffle(Words));
console.log(Words !== Shuffle(Words));
© www.soinside.com 2019 - 2024. All rights reserved.