为什么调用一个简单的辅助函数会导致无限循环?

Why is this call to a simple helper function causing an infinite loop?

我已经调试了几个小时都没有用。

以下代码检查一系列数字中的每个数字是否没有重复数字(111 应该 return false123 应该 return true) 和 return 系列中所有数字的数组,不包含重复数字。

数组应该填充数组中每个值的辅助函数 returns 作为 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) );

您忘记了 var i,因此迭代器是全局的,使用它的两个函数会相互覆盖。这最多会导致意外行为,最坏情况下会导致无限循环。

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

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

这有效地完成了您的原始函数所做的工作,但将繁重的工作卸载给内置的、较低级别的函数,这些函数通常来说速度要快得多。

这是 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;
};

引用: 将错误转化为错误

Strict mode changes some previously-accepted mistakes into errors. JavaScript was designed to be easy for novice developers, and sometimes it gives operations which should be errors non-error semantics. Sometimes this fixes the immediate problem, but sometimes this creates worse problems in the future. Strict mode treats these mistakes as errors so that they're discovered and promptly fixed.

First, strict mode makes it impossible to accidentally create global variables. In normal JavaScript mistyping a variable in an assignment creates a new property on the global object and continues to "work" (although future failure is possible: likely, in modern JavaScript). Assignments which would accidentally create global variables instead throw in strict mode:

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