反转阵列时有2个不同的输出

时间:2018-08-07 19:57:12

标签: javascript arrays reverse

我正在学习一本书中的Javascript,并且必须通过创建自己的反向函数来练习反向数组。 必须反转数组,而无需创建新变量来保存反转数组。我以为我找到了解决方案,但是当我尝试以两种不同的方式输出答案时(见下文),我得到了不同的答案。输出:

function reverseArrayInPlace(array) {
  for (var i = 0; i < array.length; i += 1) {
    array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
  }
  console.log(array);
}

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

以下是输出:

reverseArrayInPlace(array);
console.log(array);
> [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

在函数中使用console.log()时,我会得到想要的答案。

在函数外使用console.log()时,我得到了缺少最后一个元素的原始数组。 我想对此现象做出解释。

4 个答案:

答案 0 :(得分:2)

函数array的作用域与全局/窗口级的作用域不同–永远不会触及全局array;该功能改为更改其本地副本。

如果您没有将array作为参数传递给函数,则它将对现在未屏蔽的全局array变量起作用:

function reverseArrayInPlace() { // <-- no parameter
  for (var i = 0; i < array.length; i += 1) {
    array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
  }
  console.log(array);
}

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
reverseArrayInPlace();
console.log(array);

(...虽然使用这种全局变量通常是一种不好的做法,部分原因是像在这里一样,用局部变量意外地掩盖它们很容易。一种更好的模式是函数以参数和返回值,因此您可以在调用该函数时决定将返回值分配给什么。)

答案 1 :(得分:1)

for的第一个循环中,您要调用array.pop()来修改作为参数传递的数组,但是随后您将创建一个新数组,将其存储在同一变量中,因此对原始数组的引用丢失,然后在后续循环中,修改后的数组就是在函数内部生成的数组。

看看这段代码,我添加了一行来复制原始数组,因此没有修改作为参数传递的原始数组。

function reverseArrayInPlace(array) {
	array = array.slice(); //copying the passed array to not change the original
	for (var i = 0; i < array.length; i += 1) {
		array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
	}
	console.log(array);
}

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

reverseArrayInPlace(array);
console.log(array);

答案 2 :(得分:1)

reverseArrayInPlace内,您正在重新分配 array变量,而不是更改(变异)它。因此,您传入的数组不会更改。内部 console.log会看到 new array,而外部 则会看到原始的

也许您想要这样的东西

function reverseArrayInPlace(array) {
  for (var i = 0; i < array.length; i += 1) {
    array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
  }
  return array;
}

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var newArray = reverseArrayInPlace(array)

console.log(newArray)

答案 3 :(得分:1)

使用函数堆栈通过弹出值存储数组项的方法,检查数组的长度,并使用相同的对象引用再次调用该函数,然后取消临时存储的值,这是另一种方法。

尽管只使用少量值并且由于堆栈有限,所以不建议在教育目的之外使用此值。

function reverseArrayInPlace(array) {
    var temp = array.pop();
    if (array.length) {
        reverseArrayInPlace(array);
    }
    array.unshift(temp);
}

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

reverseArrayInPlace(array);

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }