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