Unsafe Negation Before in / instanceof

ID

javascript.unsafe_negation

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

reliability, suspicious-comparison

Description

Reports !a in b and !a instanceof b. Operator precedence binds the unary ! more tightly than in and instanceof, so the expression is parsed as (!a) in b — testing whether the boolean negation of a is a key of b, not the intuitive “a` is not a key of `b”.

Rationale

The two parses produce wildly different results:

  • !a in b (actual) → coerces !a to a boolean, then tests whether "true" or "false" is a key of b.

  • !(a in b) (intended) → checks whether a is not a key of b.

The misparse silently swallows the bug — the condition is almost always wrong but rarely throws.

// Bad
if (!key in obj) { ... }       // tests if "true"/"false" is a key of obj
if (!x instanceof Type) { ... } // always evaluates to false (boolean instanceof Type)

Remediation

Wrap the in / instanceof expression in parentheses before negating.

// Good
if (!(key in obj)) { ... }
if (!(x instanceof Type)) { ... }