Interview questions with answers
JavaScript puzzles interview questions and answers
“What does this print?”: hoisting, coercion, closures and the event loop. Open any question to read its model answer; the multiple-choice set marks the right option and explains it.
- Subjective
- 30
- Objective
- 30
Subjective questions 30
1What does this print, and why?Asked almost every time
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}It prints 3 3 3. var is function-scoped, so all three callbacks share one i, which is 3 by the time the timers run. With let, each iteration gets its own binding and it prints 0 1 2.
2In what order are these logged?Asked almost every time
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');A D C B. Synchronous code runs first (A, D). Then the microtask queue: the promise callback (C). Then the timer macrotask (B).
3What is logged here?Asked almost every time
console.log(a);
var a = 1;
console.log(b);
let b = 2;undefined then a ReferenceError for b. var a is hoisted and initialised to undefined. let b is hoisted but in the temporal dead zone until its declaration runs, so reading it throws.
4What does this print, and what is the fix?Asked almost every time
const arr = [10, 1, 21, 2];
console.log(arr.sort());It prints [1, 10, 2, 21]. Without a compare function, sort converts numbers to strings and sorts them by UTF-16 code units, so '10' comes before '2'. Use arr.sort((a, b) => a - b) (or toSorted) for numeric order: [1, 2, 10, 21].
5What is logged, and in what order?Asked almost every time
async function run() {
console.log(1);
setTimeout(() => console.log(2));
await null;
console.log(3);
}
run();
console.log(4);1 4 3 2. The synchronous logs run first (1, 4). await null schedules the rest of the async function as a microtask, which runs before the timer macrotask, so 3 comes before 2.
6What does this counter print?Asked almost every time
function makeCounter() {
let count = 0;
return () => ++count;
}
const a = makeCounter();
const b = makeCounter();
console.log(a(), a(), b());1 2 1. Each call to makeCounter creates a new closure with its own count. a is called twice (1, 2); b has a separate count and starts at 1.
7What does this print?Very often asked
const user = {
name: 'Asha',
getName() { return this?.name; }
};
const getName = user.getName;
console.log(getName());undefined. getName is called without an object, so this is undefined in a module or strict mode (or the global object in sloppy scripts, where name may be empty). Methods lose their this when detached; use bind or an arrow wrapper.
8Explain the output.Very often asked
console.log(['1', '2', '3'].map(parseInt));It prints [1, NaN, NaN]. map passes (value, index), so parseInt('1', 0) is 1 (radix 0 means default), parseInt('2', 1) is NaN (radix 1 is invalid) and parseInt('3', 2) is NaN (3 is not a binary digit).
9What is printed?Very often asked
function counter() {
let count = 0;
return () => ++count;
}
const next = counter();
next();
console.log(next());2. The closure keeps the count variable alive between calls; each call increments the same variable, and the second call logs 2.
10What is the result of these comparisons?Very often asked
console.log([] == false);
console.log(null == 0);
console.log(NaN !== NaN);true, false, true. [] == false converts both sides to numbers (0 == 0). null == 0 is false because null only loosely equals undefined. NaN !== NaN is true because NaN is not equal to anything, itself included; use Number.isNaN.
11What does this async function log?Very often asked
async function run() {
console.log(1);
await null;
console.log(2);
}
run();
console.log(3);1 3 2. The async function runs synchronously until the first await, logging 1. await yields, so 3 logs next, and 2 logs when the awaited promise resolves in a microtask.
12What does this print?Very often asked
var foo = 1;
function bar() {
console.log(foo);
var foo = 2;
}
bar();undefined. Inside bar, var foo is hoisted to the top of the function and shadows the outer foo, but its assignment has not run yet when it is logged. Hoisting works per function scope.
13Why does the object key collide here?Very often asked
const a = {};
const b = { key: 'b' };
const c = { key: 'c' };
a[b] = 123;
a[c] = 456;
console.log(a[b]);It prints 456. Object keys are strings, so both b and c objects are converted to the same key '[object Object]'. The second assignment overwrites the first. Use a Map to key by object identity.
14What does this print?Very often asked
function f() {
try {
return 1;
} finally {
return 2;
}
}
console.log(f());2. finally runs after try even when try returns, and a return inside finally overrides the earlier return value. Avoid returning from finally.
15What is logged for each arrow and regular function?Very often asked
const user = {
name: 'Asha',
arrow: () => this?.name,
regular() { return this.name; }
};
console.log(user.arrow(), user.regular());undefined then 'Asha'. The arrow function takes this from the surrounding scope (the module, where this is undefined), not from user. The regular method gets this from the call user.regular().
16What does this print?Very often asked
const nums = [1, 2, 3];
console.log(nums);
const copy = nums;
copy.push(4);
console.log(nums, copy);[ 1, 2, 3 ] and then [ 1, 2, 3, 4 ] for both. const prevents reassigning the variable, not changing the array. copy points to the same array, so pushing through it changes nums too.
17What is the output?Very often asked
console.log('1' == 1, '1' === 1);true false. == coerces: '1' == 1 compares as numbers. === checks type and value without coercion, so a string and a number are never strictly equal.
18Why does this print false?Often asked
console.log({ a: 1 } === { a: 1 });Objects are compared by reference, not content. The two literals are different objects in memory. Compare specific fields, or use a deep-equal function.
19What is printed?Often asked
console.log('1' + 2);
console.log('1' - 2);'12' then -1. With +, if either side is a string the other is converted and concatenated. Other arithmetic operators convert strings to numbers, so '1' - 2 is -1.
20What does this log?Often asked
const a = [1, 2, 3];
const b = a;
b.push(4);
console.log(a, b);[1, 2, 3, 4] for both. Arrays are objects held by reference; b points at the same array as a, so pushing through b changes a. Copy with [...a] to avoid it.
21What is the output?Often asked
console.log(typeof foo);
var foo = 1;
function foo() {}function. Function declarations are hoisted completely, including their body, and take precedence over the var declaration of the same name until the assignment line runs.
22What does this print?Often asked
const x = (1, 2, 3);
console.log(x);3. The comma operator evaluates each expression left to right and returns the last one.
23What is logged?Often asked
console.log(['1', '7', '11'].map(parseInt));[ 1, NaN, 3 ]. map passes (value, index), so parseInt receives the index as the radix: '1' with radix 0 (auto) is 1, '7' with radix 1 is invalid (NaN), and '11' in base 2 is 3. Use map(Number) or map(s => parseInt(s, 10)).
24What does delete do here?Often asked
const arr = [1, 2, 3];
delete arr[1];
console.log(arr, arr.length);[ 1, <1 empty item>, 3 ] and length 3. delete removes the property but leaves a hole; the length does not change. Use splice to remove items.
25What is printed?Often asked
console.log(NaN === NaN, Object.is(NaN, NaN));false true. NaN is not equal to anything, including itself. Number.isNaN and Object.is(NaN, NaN) detect it correctly.
26What does this print?Often asked
function f(a, b = a * 2) {
return b;
}
console.log(f(1));2. Default parameters are evaluated at call time and can use earlier parameters, so b becomes a * 2 = 2 when only a is passed.
27What happens with this chained assignment?Often asked
(function () {
let a = b = 5;
})();
console.log(typeof a, typeof b);undefined number. In let a = b = 5, b = 5 creates an implicit global (in sloppy mode), and a is block-scoped inside the IIFE. Outside, a is undefined but b exists.
28What does [10, 1, 3].sort() return and why?Sometimes asked
[1, 10, 3]. Without a compare function, sort converts items to strings and compares them by UTF-16 order, so '10' comes before '3'. Use sort((a, b) => a - b) for numbers.
29What does 0.1 + 0.2 print?Sometimes asked
0.30000000000000004. Numbers are IEEE 754 binary floating point, which cannot represent 0.1 and 0.2 exactly. Compare with a tolerance (Math.abs(a - b) < Number.EPSILON) or use integers for money.
30What does this print?Sometimes asked
console.log(typeof []);'object'. Arrays are objects in JavaScript; typeof cannot distinguish them. Use Array.isArray.
Objective questions 30
1What does this print?Asked almost every time
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i));
}Why: let creates a new binding per iteration.
2What is the output order?Asked almost every time
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
console.log(4);Why: Sync (1, 4), then microtask (3), then timer (2).
3What is typeof NaN?Asked almost every time
Why: NaN is a special numeric value.
4What is logged?Asked almost every time
for (let i = 1; i <= 3; i++) {
setTimeout(() => console.log(i));
}Why: let creates a fresh binding per iteration.
5What is the output?Asked almost every time
setTimeout(() => console.log('macro'));
queueMicrotask(() => console.log('micro'));
console.log('sync');Why: Sync code, then microtasks, then timers.
6What does this return?Asked almost every time
(() => { try { return 1; } finally { return 2; } })()Why: A return in finally overrides the try return.
7What does [] + {} give?Very often asked
Why: Both convert to strings: '' + '[object Object]'.
8What is logged?Very often asked
console.log(x);
const x = 5;Why: x is in the temporal dead zone before its declaration.
9What does 'b' + 'a' + +'a' + 'a' give?Very often asked
Why: +'a' is NaN, concatenated as a string.
10What is printed?Very often asked
let x = 1;
const f = () => x;
x = 2;
console.log(f());Why: The closure shares x, which changed before the call.
11What is [1, 2, 3].includes(NaN) vs [NaN].includes(NaN)?Very often asked
Why: includes uses SameValueZero, which matches NaN.
12What is logged?Very often asked
console.log((1, 2, 3));Why: The comma operator returns the last value.
13What does [...'hello'].length give?Very often asked
Why: Spreading a string gives its characters.
14What is logged?Very often asked
function f(a, b = a + 1) { return b; }
console.log(f(1));Why: Default parameters can use earlier ones.
15What is typeof []?Very often asked
Why: Use Array.isArray.
16What does Math.max() return with no arguments?Often asked
Why: It starts from -Infinity and compares upward.
17What is [1, 2, 3] + [4]?Often asked
Why: Arrays become strings '1,2,3' and '4'.
18What is null + 1?Often asked
Why: null converts to 0 in arithmetic.
19What is undefined + 1?Often asked
Why: undefined converts to NaN.
20What does this log?Often asked
const arr = [1, 2, 3];
arr[5] = 6;
console.log(arr.length);Why: Assigning index 5 leaves empty slots at 3 and 4; length is the highest index + 1.
21What does +true evaluate to?Often asked
Why: Unary plus converts to a number.
22What is '5' - 2?Often asked
Why: Minus converts strings to numbers.
23What is '5' + 2?Often asked
Why: Plus with a string concatenates.
24What is logged?Often asked
console.log({ ...{ a: 1, b: 2 }, b: 3 });Why: Later spread properties win.
25What does Boolean([]) return?Often asked
Why: All objects, even empty arrays, are truthy.
26What is [] == false?Often asked
Why: [] becomes '' then 0, and false becomes 0.
27What is !!"false"?Sometimes asked
Why: Any non-empty string is truthy.
28What does typeof function () {} return?Sometimes asked
Why: Functions report "function".
29What does Array(3).length return?Sometimes asked
Why: A sparse array with 3 empty slots.
30What is 0 || 'default'?Sometimes asked
Why: || replaces all falsy values.
Track what you have practised and search every bank in your dashboard.
Start learning