这个问题在这里已有答案:
我在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.log
output在第二个中发生的任何事情都会受到影响。
应该注意的是,如果我以一维方式定义我的数组,例如var Words = ["This", "actually", "works"];
,则不会发生这种情况。我不知道我的函数是否以某种方式无法处理2D数组,但这根本不重要,因为后来的函数调用不应该影响它之前的操作。
Javascript控制台包含数组的实时副本,而不是调用console.log()
时内容的快照。 Shuffle()
函数修改了数组。如果在调用Shuffle()
后展开数组的第一个日志的内容,它将显示当前内容,这些内容按随机顺序排列。
使用1D数组不会发生这种情况的原因是因为console.log()
会立即显示内容,而不是等待您单击显示三角形。
如果在两个调用之间设置断点,则可以查看数组的原始未抽取内容。或者您可以使用console.log(JSON.stringify(Words))
以文本格式查看快照。
它正在按预期工作,因为您正在修改输入数组。在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));