JavaScript Interview Prep
Tricky Output-Based Questions
Master tricky output-based JavaScript interview puzzles. Learn to trace coercion, scope resolution, equality checks, and object references.
1. Introduction
Output-based questions evaluate how precisely you understand JavaScript engine behavior. This lesson breaks down classic tricky output puzzles involving type coercion, scope hoisting, object references, and arithmetic operators.
2. Essential Output Puzzles
Puzzle 1: Implicit Coercion & Addition vs Subtraction
console.log(1 + '2' + 3);
console.log(1 + +'2' + 3);
console.log('10' - 5);
console.log('10' + 5);
View Output & Explanation
Output: "123", 6, 5, "105"
Explanation:
• 1 + '2' yields string "12", then "12" + 3 yields "123".
• +'2' is a unary plus converting "2" to number 2. 1 + 2 + 3 = 6.
• Subtraction operator (-) coerces strings to numbers: 10 - 5 = 5.
• Addition operator (+) concatenates when string is present: "105".
Puzzle 2: Array Equality & Object Keys Conversion
console.log([] == ![]); console.log([] == []); const a = {}; const b = { key: 'b' }; const c = { key: 'c' };
a[b] = 123; a[c] = 456; console.log(a[b]);
View Output & Explanation
Output: true, false, 456
Explanation:
• ![] evaluates to false. [] == false coerces [] to "", and "" == 0 and false == 0 -> 0 == 0 -> true.
• [] == [] compares two different object memory references in heap -> false.
• Object keys convert to strings. Both b and c convert to "[object Object]". a[b] sets a["[object Object]"] = 123, then a[c] overwrites it to 456.
Puzzle 3: Variable Hoisting vs Function Declaration Overwriting
var foo = 1; function foo() { console.log('Function foo'); } console.log(typeof foo);
function test() { console.log(a); console.log(b); var a = 10; let b = 20; } test();
View Output & Explanation
Output: "number" for typeof foo. Inside test(): undefined, then ReferenceError: Cannot access 'b' before initialization.
Explanation:
• Function declarations hoist first, but var foo = 1 assignment overwrites the function reference with the number 1.
• Inside test(), var a is hoisted with undefined. let b is hoisted into the Temporal Dead Zone (TDZ), throwing ReferenceError on access.
Puzzle 4: setTimeout Loop Closures
for (var i = 0; i < 3; i++) { setTimeout(() => console.log('var:', i), 100); }
for (let j = 0; j < 3; j++) { setTimeout(() => console.log('let:', j), 100); }
View Output & Explanation
Output: var: 3 (3 times), then let: 0, let: 1, let: 2
Explanation:
• var i creates a single function-scoped variable shared across all iterations. When callbacks execute 100ms later, i has reached 3.
• let j creates a new block-scoped binding for each iteration, preserving the value via closure.
3. Quick Quiz
Q1: What does typeof NaN evaluate to in JavaScript?
A) "undefined"
B) "number"
Answer: B — NaN stands for "Not-a-Number", but its numeric data type classification in JS specification is "number".
4. Production Considerations
- • Avoid Tricky Hacks in Production: While coercion puzzles are common in interviews, writing code that relies on implicit type coercion reduces readability. Use explicit conversions (e.g.
Number(str)orString(num)) and strict equality (===) in production.