]> git.proxmox.com Git - pve-eslint.git/blob - eslint/docs/src/rules/no-unreachable-loop.md
import 8.41.0 source
[pve-eslint.git] / eslint / docs / src / rules / no-unreachable-loop.md
1 ---
2 title: no-unreachable-loop
3 rule_type: problem
4 related_rules:
5 - no-unreachable
6 - no-constant-condition
7 - no-unmodified-loop-condition
8 - for-direction
9 ---
10
11
12 A loop that can never reach the second iteration is a possible error in the code.
13
14 ```js
15 for (let i = 0; i < arr.length; i++) {
16 if (arr[i].name === myName) {
17 doSomething(arr[i]);
18 // break was supposed to be here
19 }
20 break;
21 }
22 ```
23
24 In rare cases where only one iteration (or at most one iteration) is intended behavior, the code should be refactored to use `if` conditionals instead of `while`, `do-while` and `for` loops. It's considered a best practice to avoid using loop constructs for such cases.
25
26 ## Rule Details
27
28 This rule aims to detect and disallow loops that can have at most one iteration, by performing static code path analysis on loop bodies.
29
30 In particular, this rule will disallow a loop with a body that exits the loop in all code paths. If all code paths in the loop's body will end with either a `break`, `return` or a `throw` statement, the second iteration of such loop is certainly unreachable, regardless of the loop's condition.
31
32 This rule checks `while`, `do-while`, `for`, `for-in` and `for-of` loops. You can optionally disable checks for each of these constructs.
33
34 Examples of **incorrect** code for this rule:
35
36 ::: incorrect
37
38 ```js
39 /*eslint no-unreachable-loop: "error"*/
40
41 while (foo) {
42 doSomething(foo);
43 foo = foo.parent;
44 break;
45 }
46
47 function verifyList(head) {
48 let item = head;
49 do {
50 if (verify(item)) {
51 return true;
52 } else {
53 return false;
54 }
55 } while (item);
56 }
57
58 function findSomething(arr) {
59 for (var i = 0; i < arr.length; i++) {
60 if (isSomething(arr[i])) {
61 return arr[i];
62 } else {
63 throw new Error("Doesn't exist.");
64 }
65 }
66 }
67
68 for (key in obj) {
69 if (key.startsWith("_")) {
70 break;
71 }
72 firstKey = key;
73 firstValue = obj[key];
74 break;
75 }
76
77 for (foo of bar) {
78 if (foo.id === id) {
79 doSomething(foo);
80 }
81 break;
82 }
83 ```
84
85 :::
86
87 Examples of **correct** code for this rule:
88
89 ::: correct
90
91 ```js
92 /*eslint no-unreachable-loop: "error"*/
93
94 while (foo) {
95 doSomething(foo);
96 foo = foo.parent;
97 }
98
99 function verifyList(head) {
100 let item = head;
101 do {
102 if (verify(item)) {
103 item = item.next;
104 } else {
105 return false;
106 }
107 } while (item);
108
109 return true;
110 }
111
112 function findSomething(arr) {
113 for (var i = 0; i < arr.length; i++) {
114 if (isSomething(arr[i])) {
115 return arr[i];
116 }
117 }
118 throw new Error("Doesn't exist.");
119 }
120
121 for (key in obj) {
122 if (key.startsWith("_")) {
123 continue;
124 }
125 firstKey = key;
126 firstValue = obj[key];
127 break;
128 }
129
130 for (foo of bar) {
131 if (foo.id === id) {
132 doSomething(foo);
133 break;
134 }
135 }
136 ```
137
138 :::
139
140 Please note that this rule is not designed to check loop conditions, and will not warn in cases such as the following examples.
141
142 Examples of additional **correct** code for this rule:
143
144 ::: correct
145
146 ```js
147 /*eslint no-unreachable-loop: "error"*/
148
149 do {
150 doSomething();
151 } while (false)
152
153 for (let i = 0; i < 1; i++) {
154 doSomething(i);
155 }
156
157 for (const a of [1]) {
158 doSomething(a);
159 }
160 ```
161
162 :::
163
164 ## Options
165
166 This rule has an object option, with one option:
167
168 * `"ignore"` - an optional array of loop types that will be ignored by this rule.
169
170 ### ignore
171
172 You can specify up to 5 different elements in the `"ignore"` array:
173
174 * `"WhileStatement"` - to ignore all `while` loops.
175 * `"DoWhileStatement"` - to ignore all `do-while` loops.
176 * `"ForStatement"` - to ignore all `for` loops (does not apply to `for-in` and `for-of` loops).
177 * `"ForInStatement"` - to ignore all `for-in` loops.
178 * `"ForOfStatement"` - to ignore all `for-of` loops.
179
180 Examples of **correct** code for this rule with the `"ignore"` option:
181
182 ::: correct
183
184 ```js
185 /*eslint no-unreachable-loop: ["error", { "ignore": ["ForInStatement", "ForOfStatement"] }]*/
186
187 for (var key in obj) {
188 hasEnumerableProperties = true;
189 break;
190 }
191
192 for (const a of b) break;
193 ```
194
195 :::
196
197 ## Known Limitations
198
199 Static code path analysis, in general, does not evaluate conditions. Due to this fact, this rule might miss reporting cases such as the following:
200
201 ```js
202 for (let i = 0; i < 10; i++) {
203 doSomething(i);
204 if (true) {
205 break;
206 }
207 }
208 ```