【问题标题】:Variable assignment avoids an infinite loop变量赋值避免了无限循环
【发布时间】:2021-10-31 00:00:45
【问题描述】:

我有两段递归代码,打算递归打印出数组的一半,直到我们得到数组长度为 1 的数组。没有变量赋值的代码无限运行,而有变量赋值的代码按预期运行。

任何线索为什么会这样?

无限运行,小心

function half(arr) {
  halfway = Math.floor((arr.length) / 2)
  console.log(arr)
  if (arr.length > 1) {
    half(arr.slice(0, halfway));
    half(arr.slice(halfway));
  }
  return
}

half([1, 2, 3, 4, 5]);

不会无限运行

function half(arr) {
  halfway = Math.floor((arr.length) / 2)
  console.log(arr)
  if (arr.length > 1) {
    var a = arr.slice(0, halfway);
    var b = arr.slice(halfway);
    half(a);
    half(b);
  }
  return
}

half([1, 2, 3, 4, 5]);

我认为这里可能存在某种可变性,但我无法想象运行效果会如何。我认为每次调用函数时,我们实际上是在将一个全新的数组传递给函数......

【问题讨论】:

  • var halfway = ... -- 目前halfway 是一个被递归调用破坏的全局变量。
  • 谁能回答为什么第一个代码不输出[1,2,3,4,5]?
  • @TusharShahi 因为函数调用的可见效果是排队的,但永远没有机会出现,因为无限循环没有结束。
  • @NiettheDarkAbsol 但其他东西会打印出来吗?并且 [1,2,3,4,5] 应该是绝对第一要打印的东西。但不是吗?

标签: javascript arrays recursion


【解决方案1】:

因为缺少varletconst,所以halfway具有全局作用域,就好像你写了window.halfway一样。因此,所有递归调用都会修改并使用相同的单个变量。

第一个函数中,值在第一次递归调用中更改,然后才能用于第二次递归调用。在我的测试中,这实际上导致了一种堆栈溢出错误(或者更确切地说是最大调用堆栈大小错误),非常适合这个站点:-)。

第二个函数中,该值在递归调用开始之前被使用了两次,然后被两个函数一个接一个地修改。

使用const解决的问题:

function half1(arr) {
  const halfway = Math.floor((arr.length) / 2)
  console.log(arr.toString())
  if (arr.length > 1) {
    half1(arr.slice(0, halfway));
    half1(arr.slice(halfway));
  }
  return
}

function half2(arr) {
  const halfway = Math.floor((arr.length) / 2)
  console.log(arr.toString())
  if (arr.length > 1) {
    var a = arr.slice(0, halfway);
    var b = arr.slice(halfway);
    half2(a);
    half2(b);
  }
  return
}

const data = [1, 2, 3, 4, 5];
half1(data);
console.log("------------------------")
half2(data);

最后说明:如果您将'use strict'; 放在代码顶部,JS 编译器就会检测到并阻止整个问题。我真的不喜欢这个指令的笨拙工作方式(为什么在代码顶部放置一个“死的和未使用的”字符串会产生如此特殊和深远的影响?),但我们必须利用我们的可以得到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 2019-05-01
    • 2022-01-15
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    相关资源
    最近更新 更多