ReviseAlgo Logo

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.

Last Updated: July 29, 2026 12 min read

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) or String(num)) and strict equality (===) in production.