[英]Why is this call to a simple helper function causing an infinite loop?
我已经调试了好几个小时无济于事。
以下代码检查一系列数字中的每个数字是否没有重复数字( 111
应该返回false
; 123
应该返回true
),并返回该系列中所有不包含重复数字的所有数字的数组。
数组中应该填充值,辅助函数对数组中的每个值返回的true
,但是运行noRepeats()
会导致无限循环或1s的长数组。 是什么原因造成的?
// 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(/(.).*?\1/);
};
这可以有效地完成您原始功能的工作,但是将繁重的工作分担给内置的低级功能,这些功能通常要快得多。
这是Niet the Dark Absol的答案的附加内容。
正如他指出的那样,意外行为是由循环中使用的变量引起的。 我建议您把"use strict";
放进去"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;
};
Quote:将错误转化为错误
严格模式将一些以前可以接受的错误变为错误。 JavaScript的设计对于新手开发人员来说很容易,有时它提供的操作应该是错误和非错误的语义。 有时,这可以解决当前的问题,但有时,这会在将来造成更严重的问题。 严格模式将这些错误视为错误,以便发现并及时修复。
首先,严格模式使得不可能意外创建全局变量。 在普通的JavaScript中,迷惑分配中的变量会在全局对象上创建一个新属性,并继续“起作用” (尽管将来可能会失败:在现代JavaScript中可能)。 会意外创建全局变量的赋值会改为以严格模式抛出:
看到:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.