【问题标题】:Why is this call to a simple helper function causing an infinite loop?为什么这个对简单辅助函数的调用会导致无限循环?
【发布时间】:2016-12-06 09:40:00
【问题描述】:

我已经调试了好几个小时了。

以下代码检查一系列数字中的每个数字是否没有重复数字(111 应返回 false;123 应返回 true)并返回该系列中包含的所有数字的数组没有重复的数字。

该数组应填充辅助函数为数组中的每个值返回为true 的值,但运行noRepeats() 会导致无限循环或长1 的数组。这是什么原因造成的?

// DO NOT RUN AS IS; POTENTIAL INFINITE LOOP

var noRepeatDigits = function (n) {
  n = n.toString();
  for ( i = 0 ; i < n.length ; i ++ ) {
    for ( j = i + 1 ; j < n.length ; j ++ ) {
      if ( n.charAt(i) === n.charAt(j) ) {
        return false;
      }
    }
  }
  return true;
};

console.log( noRepeatDigits(113) ); // false
console.log( noRepeatDigits(123) ); // true

var noRepeats = function (n1, n2) {
  var arr = [];
  for ( i = n1 ; i <= n2 ; i ++ ) {
    if ( noRepeatDigits(i) ) {
      arr.push(i);
    }
  }
  return arr;
};

console.log( noRepeats(1, 100) );

【问题讨论】:

  • 好吧。设置断点并调试您的代码。

标签: javascript for-loop global-variables infinite-loop helpers


【解决方案1】:

这是 Niet the Dark Absol 答案的插件。

正如他所指出的,意外行为是由循环中使用的变量引起的。我建议您将 "use strict"; 提示放在 Javascript 的顶部。这样你就不会再犯同样的错误了。

例子:

"use strict";
// DO NOT RUN AS IS; POTENTIAL INFINITE LOOP

var noRepeatDigits = function (n) {
    n = n.toString();
    for ( i = 0 ; i < n.length ; i ++ ) {
        for ( var j = i + 1 ; j < n.length ; j ++ ) {
            if ( n.charAt(i) === n.charAt(j) ) {
                return false;
            }
        }
    }
    return true;
};

引用: 将错误转化为错误

严格模式将一些以前接受的错误变为错误。 JavaScript 旨在为新手开发人员提供方便,并且 有时它给出的操作应该是错误非错误 语义。有时这可以解决眼前的问题,但有时 这会在未来造成更严重的问题。严格模式对待这些 错误作为错误,以便被发现并及时修复。

首先,严格模式使得不可能意外创建全局 变量。在正常的 JavaScript 中,在赋值中输入错误的变量 在全局对象上创建一个新属性并继续“工作” (尽管未来的失败是可能的:在现代 JavaScript 中很可能)。 会意外创建全局变量的赋值 进入严格模式:

见:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

【讨论】:

  • @JamesBecker 你可能也对此感兴趣。
  • 我需要有人告诉我这个。我知道'use strict',但我认识的人没有人实现它。也许我应该找到更好的朋友。谢谢!
【解决方案2】:

你忘了var i,所以迭代器是全局的,使用它的两个函数会互相覆盖。这充其量会导致意外行为,最坏的情况是无限循环。

但是,您可以大大简化您的 noRepeatDigits 函数:

noRepeatDigits = function(n) {
    return !n.toString().match(/(.).*?\1/);
};

这有效地完成了您的原始函数所做的工作,但将繁重的工作转移到了内置的较低级别的函数上,这些函数一般来说速度要快得多。

【讨论】:

  • 用var i 将i 声明为局部变量解决了我的问题,谢谢。使用正则表达式匹配也确实可以简化事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多