prefer-const

声明后永远不会重新分配的变量需要 const 声明

🔧 Fixable

此规则报告的一些问题可通过 --fix 命令行选项自动修复

如果从不重新分配变量,则使用 const 声明会更好。

¥If a variable is never reassigned, using the const declaration is better.

const 声明告诉读者,“这个变量永远不会被重新分配,” 减少认知负荷,提高可维护性。

¥const declaration tells readers, “this variable is never reassigned,” reducing cognitive load and improving maintainability.

规则详情

¥Rule Details

此规则旨在标记使用 let 关键字声明但在初始分配后从未重新分配的变量。

¥This rule is aimed at flagging variables that are declared using let keyword, but never reassigned after the initial assignment.

此规则的错误代码示例:

¥Examples of incorrect code for this rule:

在线运行
/*eslint prefer-const: "error"*/

// it's initialized and never reassigned.
let a = 3;
console.log(a);

let b;
b = 0;
console.log(b);

class C {
    static {
        let a;
        a = 0;
        console.log(a);
    }
}

// `i` is redefined (not reassigned) on each loop step.
for (let i in [1, 2, 3]) {
    console.log(i);
}

// `a` is redefined (not reassigned) on each loop step.
for (let a of [1, 2, 3]) {
    console.log(a);
}

此规则的正确代码示例:

¥Examples of correct code for this rule:

在线运行
/*eslint prefer-const: "error"*/

// using const.
const a = 0;

// it's never initialized.
let b;
console.log(b);

// it's reassigned after initialized.
let c;
c = 0;
c = 1;
console.log(c);

// it's initialized in a different block from the declaration.
let d;
if (true) {
    d = 0;
}
console.log(d);

// it's initialized in a different scope.
let e;
class C {
    #x;
    static {
        e = obj => obj.#x;
    }
}

// it's initialized at a place that we cannot write a variable declaration.
let f;
if (true) f = 0;
console.log(f);

// `i` gets a new binding each iteration
for (const i in [1, 2, 3]) {
  console.log(i);
}

// `a` gets a new binding each iteration
for (const a of [1, 2, 3]) {
  console.log(a);
}

// `end` is never reassigned, but we cannot separate the declarations without modifying the scope.
for (let i = 0, end = 10; i < end; ++i) {
    console.log(i);
}

// `predicate` is only assigned once but cannot be separately declared as `const`
let predicate;
[object.type, predicate] = foo();

// `g` is only assigned once but cannot be separately declared as `const`
let g;
const h = {};
({ g, c: h.c } = func());

// suggest to use `no-var` rule.
var i = 3;
console.log(i);

选项

¥Options

{
    "prefer-const": ["error", {
        "destructuring": "any",
        "ignoreReadBeforeAssign": false
    }]
}

解构

¥destructuring

在解构中处理变量的那种方式。有 2 个值:

¥The kind of the way to address variables in destructuring. There are 2 values:

  • "any"(默认) - 如果解构中的任何变量应为 const,则此规则会针对这些变量触发警告。

    ¥"any" (default) - If any variables in destructuring should be const, this rule warns for those variables.

  • "all" - 如果解构中的所有变量都应为 const,则此规则会警告这些变量。否则,忽略它们。

    ¥"all" - If all variables in destructuring should be const, this rule warns the variables. Otherwise, ignores them.

默认 {"destructuring": "any"} 选项的错误代码示例:

¥Examples of incorrect code for the default {"destructuring": "any"} option:

在线运行
/*eslint prefer-const: "error"*/

let {a, b} = obj;    /*error 'b' is never reassigned, use 'const' instead.*/
a = a + 1;

默认 {"destructuring": "any"} 选项的正确代码示例:

¥Examples of correct code for the default {"destructuring": "any"} option:

在线运行
/*eslint prefer-const: "error"*/

// using const.
const {a: a0, b} = obj;
const a = a0 + 1;

// all variables are reassigned.
let {c, d} = obj;
c = c + 1;
d = d + 1;

{"destructuring": "all"} 选项的错误代码示例:

¥Examples of incorrect code for the {"destructuring": "all"} option:

在线运行
/*eslint prefer-const: ["error", {"destructuring": "all"}]*/

// all of `a` and `b` should be const, so those are warned.
let {a, b} = obj;    /*error 'a' is never reassigned, use 'const' instead.
                             'b' is never reassigned, use 'const' instead.*/

{"destructuring": "all"} 选项的正确代码示例:

¥Examples of correct code for the {"destructuring": "all"} option:

在线运行
/*eslint prefer-const: ["error", {"destructuring": "all"}]*/

// 'b' is never reassigned, but all of `a` and `b` should not be const, so those are ignored.
let {a, b} = obj;
a = a + 1;

ignoreReadBeforeAssign

这是一个避免与 no-use-before-define 规则冲突的选项(没有 "nofunc" 选项)。如果指定了 true,此规则将忽略在声明和第一次赋值之间读取的变量。默认为 false

¥This is an option to avoid conflicting with no-use-before-define rule (without "nofunc" option). If true is specified, this rule will ignore variables that are read between the declaration and the first assignment. Default is false.

{"ignoreReadBeforeAssign": true} 选项的正确代码示例:

¥Examples of correct code for the {"ignoreReadBeforeAssign": true} option:

在线运行
/*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": true}]*/

let timer;
function initialize() {
    if (foo()) {
        clearInterval(timer);
    }
}
timer = setInterval(initialize, 100);

默认 {"ignoreReadBeforeAssign": false} 选项的正确代码示例:

¥Examples of correct code for the default {"ignoreReadBeforeAssign": false} option:

在线运行
/*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": false}]*/

const timer = setInterval(initialize, 100);
function initialize() {
    if (foo()) {
        clearInterval(timer);
    }
}

何时不使用

¥When Not To Use It

如果你不希望收到有关在初始分配后从未重新分配的变量的通知,你可以安全地禁用此规则。

¥If you don’t want to be notified about variables that are never reassigned after initial assignment, you can safely disable this rule.

版本

此规则是在 ESLint v0.23.0 中引入。

资源

ESLint 中文网
粤ICP备13048890号