Notifications

No notifications

/Phase 1

Operators & Type Coercion

JavaScript's operators look familiar — but a few of them have famous quirks (== vs ===, + on strings, the new nullish ??). This page puts them all in one place: arithmetic, comparison, logical, plus the modern essentials — optional chaining ?., nullish coalescing ??, and template literals.

On this page

Detailed Theory

# Operators & Type Coercion

Arithmetic

1 + 2          // 3
10 / 3         // 3.333...    (no integer division)
10 % 3         // 1           (remainder)
2 ** 10        // 1024        (power)
-5             // unary minus

let n = 5; n++; // post-increment: returns 5, then n becomes 6 ++n; // pre-increment: n becomes 7, returns 7

The + operator — string OR number

+ is overloaded. If either side is a string, both sides become strings.
1 + 2          // 3
"1" + 2        // "12"        ← coercion to string
1 + "2"        // "12"
"5" - 2        // 3           ← only + does string concat; -, *, / coerce to numbers
"5" * "3"      // 15

Comparison — always use ===

opnamedoes coercion?
==loose equalyes (the famous WAT cases)
===strict equalno — types must match
!=loose !=yes
!==strict !=no

0 == false     // true   (coerced)
"" == 0        // true
null == undefined  // true   (the only useful loose-equal case)
0 === false    // false
"" === 0       // false
NaN === NaN    // false  (always)
> Rule: use === and !== everywhere. ESLint will yell at you if you don't.

Logical operators — short-circuit AND return values

&& returns the first falsy operand (or the last if all truthy). || returns the first truthy operand (or the last if all falsy).

true  && "ok"   // "ok"
false && "ok"   // false
0     && "ok"   // 0
"a"   || "b"    // "a"
""    
"b" // "b"

const name = userName

"anonymous"; // classic default fallback

?? — nullish coalescing (ES2020)

Like || but only falls back on null/undefined — NOT on 0, "", false.
0    || 100        // 100   (often a bug — 0 is a real value)
0    ?? 100        // 0     (correct — only null/undefined trigger fallback)
""   ?? "default"  // ""
null ?? "default"  // "default"

?. — optional chaining (ES2020)

Stops the chain at null/undefined instead of throwing.
const user = { profile: null };

user.profile.name // ❌ TypeError user.profile?.name // ✅ undefined user.profile?.name ?? "guest" // ✅ "guest" arr?.[0]?.toUpperCase() // works for arrays + functions too fn?.(args) // calls fn only if it exists

Ternary — cond ? a : b

const status = score >= 60 ? "pass" : "fail";
Don't nest more than one level — switch to if/else for readability.

Template literals — backticks

const name = "alice";
const greeting = hello ${name}, today is ${new Date().toDateString()};
const html = `
  <div>
    <h1>${name}</h1>
  </div>
`;

Spread ... and rest ...

Same syntax, opposite meanings.
// SPREAD — expand into individual elements
const a = [1, 2, 3];
const b = [...a, 4, 5];          // [1, 2, 3, 4, 5]
const c = { ...user, age: 22 };   // shallow merge

// REST — collect remaining args into an array function sum(...nums) { return nums.reduce((s, n) => s + n, 0); } sum(1, 2, 3, 4); // 10

Bitwise (rare but worth knowing)

5 & 3   // 1
5 | 3   // 7
5 ^ 3   // 6        XOR — neat for swap without temp
5 << 1  // 10
5 >> 1  // 2
~5      // -6       NOT