Type Coercion & Equality

Medium100% Free~20 mins#type-coercion#equality#toprimitive#implicit-coercion#javascript-traps
Key Learning Objectives
✓

Master the ECMAScript ToPrimitive algorithm and how hint ('string', 'number', 'default') is chosen.

✓

Understand the distinction between binary addition (+) and subtraction (-) type coercion.

✓

Predict the outcome of loose equality (==) vs strict equality (===) comparison chains.

✓

Explain classic JavaScript puzzles like [] == ![] and [1, 2] + [3, 4] using specification rules.

The Interview Problem

What is the exact output printed to the console when evaluating the following statements in standard ECMAScript?

1const res1 = 1 + '2' + 3;
2const res2 = 4 - '2' + '1';
3const res3 = [] == ![];
4const res4 = [1, 2] + [3, 4];
5
6console.log(res1, res2, res3, res4);
Predict Console Output
Interactive Challenge

Select the option that matches what standard ECMAScript prints to the console:

'123' '21' true '1,23,4'

6 3 false [1,2,3,4]

'123' 3 true '1,2,3,4'

'15' '21' false '10'

V8 Engine Execution Trace
Step 1 of 5 (Line 1)

Evaluate 1 + '2' + 3: Left-to-right. 1 + '2' has a string operand, so 1 coerces to '1', yielding '12'. '12' + 3 coerces 3 to '3', producing '123'.

Call Stack (Top = Active)
Global
Lexical Scope / BindingsNo active local bindings
Console Stream
> [empty]

Deep Technical Breakdown

The ECMAScript Coercion Rules

  1. Binary + vs -:
    • The + operator serves dual purposes: numeric addition and string concatenation. If either operand is an object, ToPrimitive is invoked. If either primitive operand is a string, string concatenation occurs.
    • In contrast, the -, *, /, and % operators only exist for numbers. They always convert both operands using ToNumber().
  2. The [] == ![] Equivalence Step-by-Step:
    • Step A: ![] evaluates first. [] is an object reference, hence truthy. !true becomes false.
    • Step B: Now evaluate [] == false.
    • Step C: Spec rule 7.2.14: If one operand is boolean, convert it to Number (false -> 0). Now [] == 0.
    • Step D: Object compared to number: call ToPrimitive([]). Array toString yields "". Now "" == 0.
    • Step E: String compared to number: ToNumber("") is 0. Now 0 == 0, which is strictly true!
  3. Array Concatenation Trap:
    • [1, 2] + [3, 4] does not merge arrays. Both arrays coerce via .toString() to '1,2' and '3,4'. Concatenating them results in '1,23,4'.
Common Traps & Mistakes

Assuming `==` checks identity or deep equality for objects. `==` only checks reference equality unless comparing an object to a primitive.

Assuming `Boolean([])` is false. All objects, including empty arrays `[]` and empty objects `{}`, are always truthy in JavaScript.

Believing `NaN === NaN` is true. `NaN` is the only value in JavaScript that is not equal to itself.

FAANG Follow-Up Probes
Probe #1

How does `Object.is()` differ from strict equality `===` for `-0` vs `+0` and `NaN`?

Probe #2

How does `Symbol.toPrimitive` override standard coercion behavior on custom objects?

Probe #3

Why does JavaScript specify `typeof null === 'object'` and why will it never be changed?