版本

no-loop-func

禁止在迴圈語句內包含不安全參照的函式宣告

在迴圈內撰寫函式往往會因為函式在迴圈周圍建立閉包的方式而導致錯誤。例如

for (var i = 0; i < 10; i++) {
    funcs[i] = function() {
        return i;
    };
}

在這種情況下,您會期望在迴圈內建立的每個函式都回傳不同的數字。實際上,每個函式都回傳 10,因為這是範圍內 i 的最後一個值。

letconst 可以解決這個問題。

for (let i = 0; i < 10; i++) {
    funcs[i] = function() {
        return i;
    };
}

在這種情況下,迴圈內建立的每個函式都會如預期地回傳不同的數字。

規則詳情

提出此錯誤是為了突顯一段可能無法如您預期般運作的程式碼,並且可能也表示您對語言的運作方式有所誤解。如果您不修正此錯誤,您的程式碼可能可以正常執行,但在某些情況下,它可能會出現無法預期的行為。

此規則禁止迴圈內任何包含不安全參照(例如,來自外部範圍的修改變數)的函式。此規則會忽略 IIFE,但不會忽略 async 或產生器函式。

此規則的錯誤程式碼範例

在遊樂場中開啟
/*eslint no-loop-func: "error"*/

var i = 0;
while(i < 5) {
    var a = function() { return i; };
    a();

    i++;
}

var i = 0;
do {
    function a() { return i; };
    a();

    i++
} while (i < 5);

let foo = 0;
for (let i = 0; i < 10; ++i) {
    //Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
    setTimeout(() => console.log(foo));
    foo += 1;
}

for (let i = 0; i < 10; ++i) {
    //Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
    setTimeout(() => console.log(foo));
}
foo = 100;

var arr = [];

for (var i = 0; i < 5; i++) {
    arr.push((f => f)(() => i));
}

for (var i = 0; i < 5; i++) {
    arr.push((() => {
        return () => i;
    })());
}

for (var i = 0; i < 5; i++) {
    (function fun () {
        if (arr.includes(fun)) return i;
        else arr.push(fun);
    })();
}

此規則的正確程式碼範例

在遊樂場中開啟
/*eslint no-loop-func: "error"*/

var a = function() {};

for (var i=10; i; i--) {
    a();
}

for (var i=10; i; i--) {
    var a = function() {}; // OK, no references to variables in the outer scopes.
    a();
}

for (let i=10; i; i--) {
    var a = function() { return i; }; // OK, all references are referring to block scoped variables in the loop.
    a();
}

var foo = 100;
for (let i=10; i; i--) {
    var a = function() { return foo; }; // OK, all references are referring to never modified variables.
    a();
}
//... no modifications of foo after this loop ...

var arr = [];

for (var i=10; i; i--) {
    (function() { return i; })();
}

for (var i = 0; i < 5; i++) {
    arr.push((f => f)((() => i)()));
}

for (var i = 0; i < 5; i++) {
    arr.push((() => {
        return (() => i)();
    })());
}

版本

此規則在 ESLint v0.0.9 中引入。

資源

變更語言