Type Coercion & Equality
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];56console.log(res1, res2, res3, res4);
Predict Console Output
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'.
Deep Technical Breakdown
The ECMAScript Coercion Rules
- Binary
+vs-:- The
+operator serves dual purposes: numeric addition and string concatenation. If either operand is an object,ToPrimitiveis 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 usingToNumber().
- The
- The
[] == ![]Equivalence Step-by-Step:- Step A:
![]evaluates first.[]is an object reference, hence truthy.!truebecomesfalse. - 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("")is0. Now0 == 0, which is strictlytrue!
- Step A:
- 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?
