JavaScript Core β‘ Recently updatedUpdated on Jun 30, 2026 β this content may still be evolving.
JavaScript Core: Tricky Output Questions
Predict the output before reading the answer. Say it out loud β interviewers care about your reasoning, not just the final value.
Question 1
console.log(typeof typeof 1);
π€ Predict first β then reveal the answer
Answer: "string"
Why: typeof 1 returns "number". typeof "number" returns "string" (typeof always returns a string).
Question 2
console.log(0.1 + 0.2 === 0.3);
π€ Predict first β then reveal the answer
Answer: false
Why: Floating-point precision. 0.1 + 0.2 is 0.30000000000000004. Use Number.EPSILON or round for comparisons.
Question 3
var a = 1;
function foo() {
console.log(a);
var a = 2;
}
foo();
π€ Predict first β then reveal the answer
Answer: undefined
Why: Hoisting. var a inside foo is hoisted to the top of the function, shadowing outer a. At console.log, local a exists but is uninitialized (TDZ doesnβt apply to var β itβs undefined).
Question 4
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
π€ Predict first β then reveal the answer
Answer: 3, 3, 3
Why: var is function-scoped. By the time callbacks run, loop finished and i is 3. Fix: use let (block scope) or IIFE/closure.
Question 5
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
π€ Predict first β then reveal the answer
Answer: 0, 1, 2
Why: let creates a new binding per iteration. Each callback captures its own i.
Question 6
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
π€ Predict first β then reveal the answer
Answer: 1, 4, 3, 2
Why: Sync first (1, 4). Microtasks (Promises) run before macrotasks (setTimeout). Order: call stack β microtask queue β macrotask queue.
Question 7
const obj = { a: 1, b: 2 };
const { a, b = 3 } = { a: undefined };
console.log(a, b);
π€ Predict first β then reveal the answer
Answer: undefined, 3
Why: Default values apply only when the property is undefined, not when missing. Here a is explicitly undefined, so default for b still works since b is missing from destructuring⦠Wait, let me re-read.
Actually: const { a, b = 3 } = { a: undefined };
a=undefined(property exists with value undefined)b=3(propertybdoesnβt exist on source, default applies)
Answer: undefined, 3 β
Question 8
console.log([] + []);
console.log([] + {});
console.log({} + []);
π€ Predict first β then reveal the answer
Answer: "" (empty string), "[object Object]", "[object Object]"
Why: + with objects triggers ToPrimitive. Arrays become "". {} becomes "[object Object]". In {} + [], the {} can be parsed as empty block in some contexts β in expression context itβs "[object Object]" + "".
Question 9
function foo() {
return
{
bar: 1
};
}
console.log(foo());
π€ Predict first β then reveal the answer
Answer: undefined
Why: Automatic semicolon insertion (ASI). return is treated as return; β the object on the next line is unreachable dead code.
Question 10
console.log(1 < 2 < 3);
console.log(3 > 2 > 1);
π€ Predict first β then reveal the answer
Answer: true, false
Why: Left-to-right evaluation. 1 < 2 β true. true < 3 β 1 < 3 β true. 3 > 2 β true. true > 1 β 1 > 1 β false.
Question 11
const x = { n: 1 };
const y = x;
y.n = 2;
console.log(x.n);
π€ Predict first β then reveal the answer
Answer: 2
Why: Objects are assigned by reference. x and y point to the same object.
Question 12
console.log([1, 2, 3] + [4, 5, 6]);
π€ Predict first β then reveal the answer
Answer: "1,2,34,5,6"
Why: Arrays convert to strings via toString() ("1,2,3" + "4,5,6"), then concatenated.
Question 13
function createCounter() {
let count = 0;
return {
increment: () => ++count,
getCount: () => count
};
}
const c = createCounter();
c.increment();
c.increment();
console.log(c.getCount());
console.log(c.count);
π€ Predict first β then reveal the answer
Answer: 2, undefined
Why: Closure keeps count private. Itβs not exposed as c.count β only accessible via returned methods.
Question 14
async function foo() {
return 1;
}
console.log(foo());
π€ Predict first β then reveal the answer
Answer: Promise { <fulfilled>: 1 } (or Promise { 1 })
Why: Async functions always return a Promise. return 1 wraps in resolved Promise.
Question 15
console.log('5' - 1);
console.log('5' + 1);
π€ Predict first β then reveal the answer
Answer: 4, "51"
Why: - triggers numeric coercion ('5' β 5). + with string does concatenation if either operand is string.
Question 16
const arr = [10, 20, 30];
arr[5] = 50;
console.log(arr.length);
console.log(arr[3]);
π€ Predict first β then reveal the answer
Answer: 6, undefined
Why: Setting index 5 creates sparse array. Length becomes 6. Index 3 was never set β undefined (empty slot).
Question 17
function test() {
console.log(this);
}
test();
test.call(null);
π€ Predict first β then reveal the answer
Answer (non-strict): Global object (window in browser), then global object (null/undefined coerced to global in sloppy mode).
Answer (strict mode): undefined, null
Why: In sloppy mode, standalone function calls bind this to global. call(null) also becomes global. In strict mode, this is undefined for standalone calls.
Question 18
const obj = {
name: 'JS',
greet: function() {
console.log(this.name);
},
greetArrow: () => {
console.log(this.name);
}
};
obj.greet();
obj.greetArrow();
π€ Predict first β then reveal the answer
Answer (browser): "JS", undefined (or empty β arrow inherits this from outer scope, likely window where name may be "" or undefined)
Why: Regular method: this = obj. Arrow function: this lexically bound to enclosing scope (module/global), not obj.
Practice Tip
When stuck, narrate: βIs this sync or async? Whatβs hoisted? Is this involved? Any coercion?β Interviewers reward the reasoning chain.