]>
Commit | Line | Data |
---|---|---|
8f9d1d4d DC |
1 | --- |
2 | title: no-constant-binary-expression | |
8f9d1d4d DC |
3 | rule_type: problem |
4 | related_rules: | |
5 | - no-constant-condition | |
6 | further_reading: | |
7 | - https://eslint.org/blog/2022/07/interesting-bugs-caught-by-no-constant-binary-expression/ | |
8 | --- | |
9 | ||
10 | ||
11 | Comparisons which will always evaluate to true or false and logical expressions (`||`, `&&`, `??`) which either always short-circuit or never short-circuit are both likely indications of programmer error. | |
12 | ||
13 | These errors are especially common in complex expressions where operator precedence is easy to misjudge. For example: | |
14 | ||
15 | ```js | |
16 | // One might think this would evaluate as `a + (b ?? c)`: | |
17 | const x = a + b ?? c; | |
18 | ||
19 | // But it actually evaluates as `(a + b) ?? c`. Since `a + b` can never be null, | |
20 | // the `?? c` has no effect. | |
21 | ``` | |
22 | ||
23 | Additionally, this rule detects comparisons to newly constructed objects/arrays/functions/etc. In JavaScript, where objects are compared by reference, a newly constructed object can _never_ `===` any other value. This can be surprising for programmers coming from languages where objects are compared by value. | |
24 | ||
25 | ```js | |
26 | // Programmers coming from a language where objects are compared by value might expect this to work: | |
27 | const isEmpty = x === []; | |
28 | ||
29 | // However, this will always result in `isEmpty` being `false`. | |
30 | ``` | |
31 | ||
32 | ## Rule Details | |
33 | ||
34 | This rule identifies `==` and `===` comparisons which, based on the semantics of the JavaScript language, will always evaluate to `true` or `false`. | |
35 | ||
36 | It also identifies `||`, `&&` and `??` logical expressions which will either always or never short-circuit. | |
37 | ||
38 | Examples of **incorrect** code for this rule: | |
39 | ||
40 | ::: incorrect | |
41 | ||
42 | ```js | |
43 | /*eslint no-constant-binary-expression: "error"*/ | |
44 | ||
45 | const value1 = +x == null; | |
46 | ||
47 | const value2 = condition ? x : {} || DEFAULT; | |
48 | ||
49 | const value3 = !foo == null; | |
50 | ||
51 | const value4 = new Boolean(foo) === true; | |
52 | ||
53 | const objIsEmpty = someObj === {}; | |
54 | ||
55 | const arrIsEmpty = someArr === []; | |
f2a92ac6 DC |
56 | |
57 | const shortCircuit1 = condition1 && false && condition2; | |
58 | ||
59 | const shortCircuit2 = condition1 || true || condition2; | |
60 | ||
61 | const shortCircuit3 = condition1 ?? "non-nullish" ?? condition2; | |
8f9d1d4d DC |
62 | ``` |
63 | ||
64 | ::: | |
65 | ||
66 | Examples of **correct** code for this rule: | |
67 | ||
68 | ::: correct | |
69 | ||
70 | ```js | |
71 | /*eslint no-constant-binary-expression: "error"*/ | |
72 | ||
73 | const value1 = x == null; | |
74 | ||
75 | const value2 = (condition ? x : {}) || DEFAULT; | |
76 | ||
77 | const value3 = !(foo == null); | |
78 | ||
79 | const value4 = Boolean(foo) === true; | |
80 | ||
81 | const objIsEmpty = Object.keys(someObj).length === 0; | |
82 | ||
83 | const arrIsEmpty = someArr.length === 0; | |
84 | ``` | |
85 | ||
86 | ::: |