版本

no-unreachable-loop

禁止循环体仅允许一次迭代的循环

永远无法到达第二次迭代的循环可能是代码中的错误。

for (let i = 0; i < arr.length; i++) {
    if (arr[i].name === myName) {
        doSomething(arr[i]);
        // break was supposed to be here
    }
    break;
}

在仅需要一次迭代(或最多一次迭代)作为预期行为的罕见情况下,代码应重构为使用if条件语句而不是whiledo-whilefor循环。避免在这些情况下使用循环结构被认为是一种最佳实践。

规则详情

此规则旨在通过对循环体执行静态代码路径分析来检测和禁止最多只能迭代一次的循环。

特别是,此规则将禁止循环体在所有代码路径中都退出循环的循环。如果循环体中的所有代码路径都以breakreturnthrow语句结束,则无论循环条件如何,此类循环的第二次迭代都肯定无法到达。

此规则检查whiledo-whileforfor-infor-of循环。您可以选择禁用对这些构造的检查。

此规则的错误代码示例

在在线运行中打开
/*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;
}

此规则的正确代码示例

在在线运行中打开
/*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;
    }
}

请注意,此规则并非旨在检查循环条件,并且在以下示例等情况下不会发出警告。

此规则的其他正确代码示例

在在线运行中打开
/*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);
}

选项

此规则有一个对象选项,带有一个选项

  • "ignore" - 一个可选的循环类型数组,此规则将忽略这些类型。

ignore

您可以在"ignore"数组中指定最多 5 个不同的元素

  • "WhileStatement" - 忽略所有while循环。
  • "DoWhileStatement" - 忽略所有do-while循环。
  • "ForStatement" - 忽略所有for循环(不适用于for-infor-of循环)。
  • "ForInStatement" - 忽略所有for-in循环。
  • "ForOfStatement" - 忽略所有for-of循环。

使用"ignore"选项的此规则的正确代码示例

在在线运行中打开
/*eslint no-unreachable-loop: ["error", { "ignore": ["ForInStatement", "ForOfStatement"] }]*/

for (var key in obj) {
  hasEnumerableProperties = true;
  break;
}

for (const a of b) break;

已知限制

一般来说,静态代码路径分析不会评估条件。由于这个事实,此规则可能会错过报告以下情况

for (let i = 0; i < 10; i++) {
    doSomething(i);
    if (true) {
        break;
    }
}

版本

此规则是在 ESLint v7.3.0 中引入的。

资源

更改语言