Js:为什么要转移而不是推动?

Js: Why shift and not push?

我想做一个简单的倒计时函数,如果我将 10 作为参数传递,应该 return 一个像 [10,9,8,7,6,5,4, 3,2,1]

我认为每次我的参数“n”传入下面的这个递归函数时,我只需要将新值“n”压入数组即可。但是这里好像push方法不合适,需要unshift方法,如下图

但是为什么呢?我不明白逻辑。

下面:推送 n 的函数:

function countdown(n){
  if (n < 1) {
    return []
  } 
  let array = []
  array = countdown(n-1)
  array.push(n)
  return array
}

console.log(countdown(10))

[1,2,3,4,5,6,7,8,9,10]

下面,取消 n 移位的函数:

function countdown(n){
  if (n < 1) {
    return []
  } 
  let array = []
  array = countdown(n-1)
  array.unshift(n)
  return array
}

console.log(countdown(10))

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

也许简化递归函数更容易表明,如果需要更多值,它 returns 一个具有实际值的数组和一个展开的剩余数组。

要得到一个降序排列的数组,需要将最大的值放在左边,其余的放在右边。这意味着 push 是错误的,而 unshift 是正确的。

function countdown(n) {
    if (n < 1) return []
    return [n, ...countdown(n - 1)];
}

console.log(countdown(10));

push 视为堆栈从左到右的压入操作。在这种情况下,它会简单地将一个元素推到堆栈的顶部(这里的顶部是最右边的元素)

unshift 就像队列中的入队函数,从左到右。这会将一个元素添加到队列的末尾(最左侧),队列的开头将被推得更远一点(向右)。

Array.push() adds elements to the end of the array.

对于 countdown()Array.push() 实现,递归函数首先计算所有较小的数组元素 (array = countdown(n-1)。然后,在递归调用之后,pushn 添加到数组中。所以对于 countdown(2) 数组是:

countdown(1).push(2) 

并且由于 countdown(1)countdown(0).push(1),而 countdown(0)[],我们可以将其扩展为

[].push(1).push(2)

最终看起来像

[]
[1]
[1, 2]

因此我们可以看到 push 实现将连续较大的值附加到数组的末尾。

另一方面,

Array.unshift() 将元素添加到数组的开头。因此,按照与以前相同的递归“扩展”,unshift 实现将连续较大的值添加到数组的前面。 countdown(2) 变为 countdown(1).unshift(2)[2].push(countdown(1) 基本相同。所以输出经过步骤

[]
[1]
[2, 1]