]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | # Disallow mixes of different operators (no-mixed-operators) |
2 | ||
3 | Enclosing complex expressions by parentheses clarifies the developer's intention, which makes the code more readable. | |
4 | This rule warns when different operators are used consecutively without parentheses in an expression. | |
5 | ||
6 | ```js | |
7 | var foo = a && b || c || d; /*BAD: Unexpected mix of '&&' and '||'.*/ | |
8 | var foo = a && b ? c : d; /*BAD: Unexpected mix of '&&' and '?:'.*/ | |
9 | var foo = (a && b) ? c : d; /*GOOD*/ | |
10 | var foo = (a && b) || c || d; /*GOOD*/ | |
11 | var foo = a && (b || c || d); /*GOOD*/ | |
12 | ``` | |
13 | ||
14 | **Note:** | |
15 | It is expected for this rule to emit one error for each mixed operator in a pair. As a result, for each two consecutive mixed operators used, a distinct error will be displayed, pointing to where the specific operator that breaks the rule is used: | |
16 | ||
17 | ```js | |
18 | var foo = a && b || c || d; | |
19 | ``` | |
20 | ||
21 | will generate | |
22 | ||
23 | ```sh | |
24 | 1:13 Unexpected mix of '&&' and '||'. (no-mixed-operators) | |
25 | 1:18 Unexpected mix of '&&' and '||'. (no-mixed-operators) | |
26 | ``` | |
27 | ||
28 | ```js | |
29 | var foo = a && b ? c : d; | |
30 | ``` | |
31 | ||
32 | will generate | |
33 | ||
34 | ```sh | |
35 | 1:13 Unexpected mix of '&&' and '?:'. (no-mixed-operators) | |
36 | 1:18 Unexpected mix of '&&' and '?:'. (no-mixed-operators) | |
37 | ``` | |
38 | ||
eb39fafa DC |
39 | ## Rule Details |
40 | ||
41 | This rule checks `BinaryExpression`, `LogicalExpression` and `ConditionalExpression`. | |
42 | ||
43 | This rule may conflict with [no-extra-parens](no-extra-parens.md) rule. | |
44 | If you use both this and [no-extra-parens](no-extra-parens.md) rule together, you need to use the `nestedBinaryExpressions` option of [no-extra-parens](no-extra-parens.md) rule. | |
45 | ||
46 | Examples of **incorrect** code for this rule: | |
47 | ||
48 | ```js | |
49 | /*eslint no-mixed-operators: "error"*/ | |
50 | ||
51 | var foo = a && b < 0 || c > 0 || d + 1 === 0; | |
52 | var foo = a + b * c; | |
53 | ``` | |
54 | ||
55 | Examples of **correct** code for this rule: | |
56 | ||
57 | ```js | |
58 | /*eslint no-mixed-operators: "error"*/ | |
59 | ||
60 | var foo = a || b || c; | |
61 | var foo = a && b && c; | |
62 | var foo = (a && b < 0) || c > 0 || d + 1 === 0; | |
63 | var foo = a && (b < 0 || c > 0 || d + 1 === 0); | |
64 | var foo = a + (b * c); | |
65 | var foo = (a + b) * c; | |
66 | ``` | |
67 | ||
68 | ## Options | |
69 | ||
70 | ```json | |
71 | { | |
72 | "no-mixed-operators": [ | |
73 | "error", | |
74 | { | |
75 | "groups": [ | |
76 | ["+", "-", "*", "/", "%", "**"], | |
77 | ["&", "|", "^", "~", "<<", ">>", ">>>"], | |
78 | ["==", "!=", "===", "!==", ">", ">=", "<", "<="], | |
79 | ["&&", "||"], | |
80 | ["in", "instanceof"] | |
81 | ], | |
82 | "allowSamePrecedence": true | |
83 | } | |
84 | ] | |
85 | } | |
86 | ``` | |
87 | ||
88 | This rule has 2 options. | |
89 | ||
90 | * `groups` (`string[][]`) - specifies operator groups to be checked. The `groups` option is a list of groups, and a group is a list of binary operators. Default operator groups are defined as arithmetic, bitwise, comparison, logical, and relational operators. Note: Ternary operator(?:) can be part of any group and by default is allowed to be mixed with other operators. | |
91 | ||
92 | * `allowSamePrecedence` (`boolean`) - specifies whether to allow mixed operators if they are of equal precedence. Default is `true`. | |
93 | ||
94 | ### groups | |
95 | ||
96 | The following operators can be used in `groups` option: | |
97 | ||
98 | * Arithmetic Operators: `"+"`, `"-"`, `"*"`, `"/"`, `"%"`, `"**"` | |
99 | * Bitwise Operators: `"&"`, `"|"`, `"^"`, `"~"`, `"<<"`, `">>"`, `">>>"` | |
100 | * Comparison Operators: `"=="`, `"!="`, `"==="`, `"!=="`, `">"`, `">="`, `"<"`, `"<="` | |
101 | * Logical Operators: `"&&"`, `"||"` | |
d3726936 | 102 | * Coalesce Operator: `"??"` |
eb39fafa DC |
103 | * Relational Operators: `"in"`, `"instanceof"` |
104 | * Ternary Operator: `?:` | |
105 | ||
106 | Now, consider the following group configuration: `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}`. | |
107 | There are 2 groups specified in this configuration: bitwise operators and logical operators. | |
108 | This rule checks if the operators belong to the same group only. | |
109 | In this case, this rule checks if bitwise operators and logical operators are mixed, but ignores all other operators. | |
110 | ||
111 | Examples of **incorrect** code for this rule with `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}` option: | |
112 | ||
113 | ```js | |
114 | /*eslint no-mixed-operators: ["error", {"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}]*/ | |
115 | ||
116 | var foo = a && b < 0 || c > 0 || d + 1 === 0; | |
117 | var foo = a & b | c; | |
118 | ``` | |
119 | ||
120 | ```js | |
121 | /*eslint no-mixed-operators: ["error", {"groups": [["&&", "||", "?:"]]}]*/ | |
122 | ||
123 | var foo = a || b ? c : d; | |
5422a9cc TL |
124 | |
125 | var bar = a ? b || c : d; | |
126 | ||
127 | var baz = a ? b : c || d; | |
eb39fafa DC |
128 | ``` |
129 | ||
130 | Examples of **correct** code for this rule with `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}` option: | |
131 | ||
132 | ```js | |
133 | /*eslint no-mixed-operators: ["error", {"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}]*/ | |
134 | ||
135 | var foo = a || b > 0 || c + 1 === 0; | |
136 | var foo = a && b > 0 && c + 1 === 0; | |
137 | var foo = (a && b < 0) || c > 0 || d + 1 === 0; | |
138 | var foo = a && (b < 0 || c > 0 || d + 1 === 0); | |
139 | var foo = (a & b) | c; | |
140 | var foo = a & (b | c); | |
141 | var foo = a + b * c; | |
142 | var foo = a + (b * c); | |
143 | var foo = (a + b) * c; | |
144 | ``` | |
145 | ||
146 | ```js | |
147 | /*eslint no-mixed-operators: ["error", {"groups": [["&&", "||", "?:"]]}]*/ | |
148 | ||
149 | var foo = (a || b) ? c : d; | |
150 | var foo = a || (b ? c : d); | |
5422a9cc TL |
151 | |
152 | var bar = a ? (b || c) : d; | |
153 | ||
154 | var baz = a ? b : (c || d); | |
155 | var baz = (a ? b : c) || d; | |
eb39fafa DC |
156 | ``` |
157 | ||
158 | ### allowSamePrecedence | |
159 | ||
160 | Examples of **correct** code for this rule with `{"allowSamePrecedence": true}` option: | |
161 | ||
162 | ```js | |
163 | /*eslint no-mixed-operators: ["error", {"allowSamePrecedence": true}]*/ | |
164 | ||
165 | // + and - have the same precedence. | |
166 | var foo = a + b - c; | |
167 | ``` | |
168 | ||
169 | Examples of **incorrect** code for this rule with `{"allowSamePrecedence": false}` option: | |
170 | ||
171 | ```js | |
172 | /*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/ | |
173 | ||
174 | // + and - have the same precedence. | |
175 | var foo = a + b - c; | |
176 | ``` | |
177 | ||
178 | Examples of **correct** code for this rule with `{"allowSamePrecedence": false}` option: | |
179 | ||
180 | ```js | |
181 | /*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/ | |
182 | ||
183 | // + and - have the same precedence. | |
184 | var foo = (a + b) - c; | |
185 | ``` | |
186 | ||
187 | ## When Not To Use It | |
188 | ||
189 | If you don't want to be notified about mixed operators, then it's safe to disable this rule. | |
190 | ||
191 | ## Related Rules | |
192 | ||
193 | * [no-extra-parens](no-extra-parens.md) |