]> git.proxmox.com Git - pve-eslint.git/blob - eslint/docs/src/rules/prefer-const.md
import 8.41.0 source
[pve-eslint.git] / eslint / docs / src / rules / prefer-const.md
1 ---
2 title: prefer-const
3 rule_type: suggestion
4 related_rules:
5 - no-var
6 - no-use-before-define
7 ---
8
9
10
11 If a variable is never reassigned, using the `const` declaration is better.
12
13 `const` declaration tells readers, "this variable is never reassigned," reducing cognitive load and improving maintainability.
14
15 ## Rule Details
16
17 This rule is aimed at flagging variables that are declared using `let` keyword, but never reassigned after the initial assignment.
18
19 Examples of **incorrect** code for this rule:
20
21 ::: incorrect
22
23 ```js
24 /*eslint prefer-const: "error"*/
25
26 // it's initialized and never reassigned.
27 let a = 3;
28 console.log(a);
29
30 let a;
31 a = 0;
32 console.log(a);
33
34 class C {
35 static {
36 let a;
37 a = 0;
38 console.log(a);
39 }
40 }
41
42 // `i` is redefined (not reassigned) on each loop step.
43 for (let i in [1, 2, 3]) {
44 console.log(i);
45 }
46
47 // `a` is redefined (not reassigned) on each loop step.
48 for (let a of [1, 2, 3]) {
49 console.log(a);
50 }
51 ```
52
53 :::
54
55 Examples of **correct** code for this rule:
56
57 ::: correct
58
59 ```js
60 /*eslint prefer-const: "error"*/
61
62 // using const.
63 const a = 0;
64
65 // it's never initialized.
66 let a;
67 console.log(a);
68
69 // it's reassigned after initialized.
70 let a;
71 a = 0;
72 a = 1;
73 console.log(a);
74
75 // it's initialized in a different block from the declaration.
76 let a;
77 if (true) {
78 a = 0;
79 }
80 console.log(a);
81
82 // it's initialized in a different scope.
83 let a;
84 class C {
85 #x;
86 static {
87 a = obj => obj.#x;
88 }
89 }
90
91 // it's initialized at a place that we cannot write a variable declaration.
92 let a;
93 if (true) a = 0;
94 console.log(a);
95
96 // `i` gets a new binding each iteration
97 for (const i in [1, 2, 3]) {
98 console.log(i);
99 }
100
101 // `a` gets a new binding each iteration
102 for (const a of [1, 2, 3]) {
103 console.log(a);
104 }
105
106 // `end` is never reassigned, but we cannot separate the declarations without modifying the scope.
107 for (let i = 0, end = 10; i < end; ++i) {
108 console.log(i);
109 }
110
111 // `predicate` is only assigned once but cannot be separately declared as `const`
112 let predicate;
113 [object.type, predicate] = foo();
114
115 // `a` is only assigned once but cannot be separately declared as `const`
116 let a;
117 const b = {};
118 ({ a, c: b.c } = func());
119
120 // suggest to use `no-var` rule.
121 var b = 3;
122 console.log(b);
123 ```
124
125 :::
126
127 ## Options
128
129 ```json
130 {
131 "prefer-const": ["error", {
132 "destructuring": "any",
133 "ignoreReadBeforeAssign": false
134 }]
135 }
136 ```
137
138 ### destructuring
139
140 The kind of the way to address variables in destructuring.
141 There are 2 values:
142
143 * `"any"` (default) - If any variables in destructuring should be `const`, this rule warns for those variables.
144 * `"all"` - If all variables in destructuring should be `const`, this rule warns the variables. Otherwise, ignores them.
145
146 Examples of **incorrect** code for the default `{"destructuring": "any"}` option:
147
148 ::: incorrect
149
150 ```js
151 /*eslint prefer-const: "error"*/
152 /*eslint-env es6*/
153
154 let {a, b} = obj; /*error 'b' is never reassigned, use 'const' instead.*/
155 a = a + 1;
156 ```
157
158 :::
159
160 Examples of **correct** code for the default `{"destructuring": "any"}` option:
161
162 ::: correct
163
164 ```js
165 /*eslint prefer-const: "error"*/
166 /*eslint-env es6*/
167
168 // using const.
169 const {a: a0, b} = obj;
170 const a = a0 + 1;
171
172 // all variables are reassigned.
173 let {a, b} = obj;
174 a = a + 1;
175 b = b + 1;
176 ```
177
178 :::
179
180 Examples of **incorrect** code for the `{"destructuring": "all"}` option:
181
182 ::: incorrect
183
184 ```js
185 /*eslint prefer-const: ["error", {"destructuring": "all"}]*/
186 /*eslint-env es6*/
187
188 // all of `a` and `b` should be const, so those are warned.
189 let {a, b} = obj; /*error 'a' is never reassigned, use 'const' instead.
190 'b' is never reassigned, use 'const' instead.*/
191 ```
192
193 :::
194
195 Examples of **correct** code for the `{"destructuring": "all"}` option:
196
197 ::: correct
198
199 ```js
200 /*eslint prefer-const: ["error", {"destructuring": "all"}]*/
201 /*eslint-env es6*/
202
203 // 'b' is never reassigned, but all of `a` and `b` should not be const, so those are ignored.
204 let {a, b} = obj;
205 a = a + 1;
206 ```
207
208 :::
209
210 ### ignoreReadBeforeAssign
211
212 This is an option to avoid conflicting with `no-use-before-define` rule (without `"nofunc"` option).
213 If `true` is specified, this rule will ignore variables that are read between the declaration and the first assignment.
214 Default is `false`.
215
216 Examples of **correct** code for the `{"ignoreReadBeforeAssign": true}` option:
217
218 ::: correct
219
220 ```js
221 /*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": true}]*/
222 /*eslint-env es6*/
223
224 let timer;
225 function initialize() {
226 if (foo()) {
227 clearInterval(timer);
228 }
229 }
230 timer = setInterval(initialize, 100);
231 ```
232
233 :::
234
235 Examples of **correct** code for the default `{"ignoreReadBeforeAssign": false}` option:
236
237 ::: correct
238
239 ```js
240 /*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": false}]*/
241 /*eslint-env es6*/
242
243 const timer = setInterval(initialize, 100);
244 function initialize() {
245 if (foo()) {
246 clearInterval(timer);
247 }
248 }
249 ```
250
251 :::
252
253 ## When Not To Use It
254
255 If you don't want to be notified about variables that are never reassigned after initial assignment, you can safely disable this rule.