> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/eslint/eslint/llms.txt
> Use this file to discover all available pages before exploring further.

# no-constant-binary-expression

> Disallow expressions where the operation doesn't affect the value

# no-constant-binary-expression

Comparisons that always evaluate to true or false, and logical expressions that either always short-circuit or never short-circuit, are usually programmer errors.

<Note>
  **Rule Type:** Problem\
  **Fixable:** No
</Note>

## Why This Rule Exists

These errors are especially common in complex expressions where operator precedence is easy to misjudge:

```js theme={null}
// This looks like: a + (b ?? c)
const x = a + b ?? c;

// But it actually evaluates as: (a + b) ?? c
// Since a + b can never be null, the ?? c has no effect!
```

Also, comparing newly constructed objects by reference will always be `false`, which can surprise developers from other languages:

```js theme={null}
// This always returns false (objects compared by reference)
const isEmpty = x === [];
```

## Rule Details

This rule identifies:

* `==` and `===` comparisons that always evaluate to `true` or `false`
* `||`, `&&`, and `??` expressions that always or never short-circuit

## Examples

### Incorrect Code

```js theme={null}
// Unary plus always produces a number, never null
const value1 = +x == null;

// Empty object is always truthy, so || DEFAULT never runs
const value2 = condition ? x : {} || DEFAULT;

// !foo is boolean, never null
const value3 = !foo == null;

// new Boolean creates an object, never === true
const value4 = new Boolean(foo) === true;

// Comparing with newly constructed object (always false)
const objIsEmpty = someObj === {};
const arrIsEmpty = someArr === [];

// Always short-circuits at false
const shortCircuit1 = condition1 && false && condition2;

// Always short-circuits at true
const shortCircuit2 = condition1 || true || condition2;

// Always short-circuits at "non-nullish"
const shortCircuit3 = condition1 ?? "non-nullish" ?? condition2;
```

### Correct Code

```js theme={null}
// Check x directly for null
const value1 = x == null;

// Parenthesize to make intent clear
const value2 = (condition ? x : {}) || DEFAULT;

// Negate the comparison, not the value
const value3 = !(foo == null);

// Use Boolean function (not constructor)
const value4 = Boolean(foo) === true;

// Check actual emptiness
const objIsEmpty = Object.keys(someObj).length === 0;
const arrIsEmpty = someArr.length === 0;

// Conditions that can actually vary
const shortCircuit1 = condition1 && condition2;
const shortCircuit2 = condition1 || condition2;
const shortCircuit3 = condition1 ?? condition2;
```

## Common Patterns

### Object/Array Comparisons

<Warning>
  In JavaScript, objects are compared by reference, not by value. A new object never equals any other value.
</Warning>

```js theme={null}
// Wrong: Always false
if (user === {}) { }
if (arr === []) { }
if (regex === /test/) { }

// Right: Check properties or length
if (Object.keys(user).length === 0) { }
if (arr.length === 0) { }
```

### Type Coercion Issues

```js theme={null}
// Wrong: Unary + converts to number, never null
if (+value == null) { }

// Right: Check before converting
if (value == null) { }
if (isNaN(+value)) { }
```

### Operator Precedence

```js theme={null}
// Wrong: && has higher precedence than ||
const result = a || b && c; // Means: a || (b && c)

// Wrong: + has higher precedence than ??
const value = a + b ?? c; // Means: (a + b) ?? c

// Right: Use parentheses for clarity
const result = (a || b) && c;
const value = a + (b ?? c);
```

### Constructor vs Function

```js theme={null}
// Wrong: Constructor creates object, not boolean
const value = new Boolean(foo) === true;
const value = new Number(x) === 0;
const value = new String(s) === "";

// Right: Use function form
const value = Boolean(foo) === true;
const value = Number(x) === 0;
const value = String(s) === "";

// Even better: Use simple comparison
const value = !!foo;
const value = x === 0;
const value = s === "";
```

## When Not to Use It

This rule has no legitimate use cases for disabling - constant expressions are always mistakes. If you need to disable it for a specific line, you may have found a false positive bug in ESLint.

## Related Rules

* [no-constant-condition](/rules/no-constant-condition)
* [eqeqeq](/rules/eqeqeq)

## Further Reading

* [ESLint Blog: Interesting Bugs Caught by no-constant-binary-expression](https://eslint.org/blog/2022/07/interesting-bugs-caught-by-no-constant-binary-expression/)
