版本

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 中引入。

資源

變更語言