no-unreachable-loop
不允许循环体只允许一次迭代
永远无法到达第二次迭代的循环可能是代码中的错误。
¥A loop that can never reach the second iteration is a possible error in the code.
for (let i = 0; i < arr.length; i++) {
if (arr[i].name === myName) {
doSomething(arr[i]);
// break was supposed to be here
}
break;
}
在只有一次迭代(或最多一次迭代)是预期行为的极少数情况下,应重构代码以使用 if
条件而不是 while
、do-while
和 for
循环。在这种情况下避免使用循环构造被认为是最佳实践。
¥In rare cases where only one iteration (or at most one iteration) is intended behavior, the code should be refactored to use if
conditionals instead of while
, do-while
and for
loops. It’s considered a best practice to avoid using loop constructs for such cases.
规则详情
¥Rule Details
此规则旨在通过对循环体执行静态代码路径分析来检测和禁止最多可以进行一次迭代的循环。
¥This rule aims to detect and disallow loops that can have at most one iteration, by performing static code path analysis on loop bodies.
特别是,该规则将禁止循环体的主体在所有代码路径中都退出循环。如果循环体中的所有代码路径都以 break
、return
或 throw
语句结尾,那么无论循环的条件如何,这种循环的第二次迭代肯定是无法到达的。
¥In particular, this rule will disallow a loop with a body that exits the loop in all code paths. If all code paths in the loop’s body will end with either a break
, return
or a throw
statement, the second iteration of such loop is certainly unreachable, regardless of the loop’s condition.
此规则检查 while
、do-while
、for
、for-in
和 for-of
循环。你可以选择禁用对这些构造中的每一个的检查。
¥This rule checks while
, do-while
, for
, for-in
and for-of
loops. You can optionally disable checks for each of these constructs.
此规则的错误代码示例:
¥Examples of incorrect code for this rule:
/*eslint no-unreachable-loop: "error"*/
while (foo) {
doSomething(foo);
foo = foo.parent;
break;
}
function verifyList(head) {
let item = head;
do {
if (verify(item)) {
return true;
} else {
return false;
}
} while (item);
}
function findSomething(arr) {
for (var i = 0; i < arr.length; i++) {
if (isSomething(arr[i])) {
return arr[i];
} else {
throw new Error("Doesn't exist.");
}
}
}
for (key in obj) {
if (key.startsWith("_")) {
break;
}
firstKey = key;
firstValue = obj[key];
break;
}
for (foo of bar) {
if (foo.id === id) {
doSomething(foo);
}
break;
}
此规则的正确代码示例:
¥Examples of correct code for this rule:
/*eslint no-unreachable-loop: "error"*/
while (foo) {
doSomething(foo);
foo = foo.parent;
}
function verifyList(head) {
let item = head;
do {
if (verify(item)) {
item = item.next;
} else {
return false;
}
} while (item);
return true;
}
function findSomething(arr) {
for (var i = 0; i < arr.length; i++) {
if (isSomething(arr[i])) {
return arr[i];
}
}
throw new Error("Doesn't exist.");
}
for (key in obj) {
if (key.startsWith("_")) {
continue;
}
firstKey = key;
firstValue = obj[key];
break;
}
for (foo of bar) {
if (foo.id === id) {
doSomething(foo);
break;
}
}
请注意,此规则并非旨在检查循环条件,并且不会在以下示例中触发警告。
¥Please note that this rule is not designed to check loop conditions, and will not warn in cases such as the following examples.
此规则的附加正确代码示例:
¥Examples of additional correct code for this rule:
/*eslint no-unreachable-loop: "error"*/
do {
doSomething();
} while (false)
for (let i = 0; i < 1; i++) {
doSomething(i);
}
for (const a of [1]) {
doSomething(a);
}
选项
¥Options
此规则有一个对象选项,有一个选项:
¥This rule has an object option, with one option:
-
"ignore"
- 此规则将忽略的循环类型的可选数组。¥
"ignore"
- an optional array of loop types that will be ignored by this rule.
ignore
你可以在 "ignore"
数组中指定最多 5 个不同的元素:
¥You can specify up to 5 different elements in the "ignore"
array:
-
"WhileStatement"
- 忽略所有while
循环。¥
"WhileStatement"
- to ignore allwhile
loops. -
"DoWhileStatement"
- 忽略所有do-while
循环。¥
"DoWhileStatement"
- to ignore alldo-while
loops. -
"ForStatement"
- 忽略所有for
循环(不适用于for-in
和for-of
循环)。¥
"ForStatement"
- to ignore allfor
loops (does not apply tofor-in
andfor-of
loops). -
"ForInStatement"
- 忽略所有for-in
循环。¥
"ForInStatement"
- to ignore allfor-in
loops. -
"ForOfStatement"
- 忽略所有for-of
循环。¥
"ForOfStatement"
- to ignore allfor-of
loops.
使用 "ignore"
选项的此规则的正确代码示例:
¥Examples of correct code for this rule with the "ignore"
option:
/*eslint no-unreachable-loop: ["error", { "ignore": ["ForInStatement", "ForOfStatement"] }]*/
for (var key in obj) {
hasEnumerableProperties = true;
break;
}
for (const a of b) break;
已知限制
¥Known Limitations
静态代码路径分析通常不评估条件。由于这一事实,此规则可能会遗漏报告案例,例如:
¥Static code path analysis, in general, does not evaluate conditions. Due to this fact, this rule might miss reporting cases such as the following:
for (let i = 0; i < 10; i++) {
doSomething(i);
if (true) {
break;
}
}
相关规则
版本
此规则是在 ESLint v7.3.0 中引入。