Photo by chansu shin on Unsplash

On this page

This chapter follows Variables and declarations.

Equality: === and ==

Prefer === (strict equality) and !==. No implicit type conversion. == coerces types (for example "5" == 5 is true) and is a common source of bugs; linters often forbid it.

equality.js
0 === false; // false
0 == false; // true (coercion)
Object.is(NaN, NaN); // true; NaN === NaN is false
Object.is(+0, -0); // false; +0 === -0 is true

Object.is matches SameValue semantics used internally (for example in Map keys).

Logical operators

&& and || return operands, not booleans, when used as expressions—unlike many languages that always yield true/false.

logical.js
const name = user.nickname || user.name || "guest";
const port = config.port ?? 3000; // see nullish coalescing
const ok = enabled && run(); // run() skipped if enabled is falsy

Short-circuit evaluation matches other languages; the returned value is what differs.

Nullish coalescing (??)

?? returns the right side only when the left is null or undefined, not when it is 0, "", or false. That makes it the right default for numeric and string settings where || would swallow valid values.

nullish.js
const retries = options.retries ?? 3;
0 ?? 10; // 0
0 || 10; // 10

You cannot mix ?? with && or || without parentheses—syntax error.

Optional chaining (?., ?[], ?())

Optional chaining stops evaluation and yields undefined when the base is null or undefined.

optional.js
const city = user?.address?.city;
const first = arr?.[0];
const result = callback?.(arg);

It does not catch errors from invalid property access on non-null objects (wrong key on a plain object still returns undefined without throwing).

Assignment and logical assignment

Compound assignment (+=, &&=, ||=, ??=) evaluates the right side and assigns. Logical assignment updates only when the left side passes the operator’s test.

assign.js
let count = 0;
count ||= 1; // assign 1 only if count is falsy
let cfg = null;
cfg ??= { debug: false }; // assign because cfg is nullish

Destructuring assignment ([a, b] = tuple) is covered in Destructuring and spread.

Operator precedence (essentials)

Higher precedence binds tighter. When in doubt, use parentheses.

Operators (high → low among common ones) Notes
?. () [] Member and call
++ -- ! typeof Unary
* / % Multiplicative
+ - Additive; + also string concat
< <= > >= in instanceof Relational
== != === !== Equality
&& Then ||
?? Lower than ||; use parens when mixing
? : Conditional
= += ??= … Assignment

The conditional operator ? : is an expression (unlike Python’s if/else expression in recent versions, JavaScript has had this from the start).

typeof and void

typeof null is "object" (historical bug). Use === null or optional chaining instead of relying on typeof for null checks.

void expression evaluates the expression and returns undefined—occasionally used to force an undefined result in legacy patterns.

Next: Control flow in JavaScript.

Search articles

Type a word to search published articles.

Open the search page