JavaScript interviews often include tricky output-based questions that test your understanding of scoping, hoisting, closures, this, and more. Below is a detailed blog-style guide that walks through 25 frequently asked JS MCQ problems with their answers and clear explanations.
🔥 1. Hoisting & TDZ
function sayHi() {
console.log(name);
console.log(age);
var name = 'Lydia';
let age = 21;
}
sayHi();
Answer: D — undefined and ReferenceError
Why:
• var name is hoisted and defaults to undefined until assignment.
• let age is hoisted but not initialized — so accessing it before declaration throws a ReferenceError.
This is due to the Temporal Dead Zone (TDZ) for let/const. ([Medium][1])
🔥 2. Loop + setTimeout
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1);
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1);
}
Answer: C — 3 3 3 and 0 1 2
Why:
• var is function scoped → by the time callbacks run, i is 3.
• let is block scoped → each iteration captures its own i. ([Medium][1])
🔥 3. this in regular vs arrow
const shape = {
radius: 10,
diameter() {
return this.radius * 2;
},
perimeter: () => 2 * Math.PI * this.radius,
};
console.log(shape.diameter());
console.log(shape.perimeter());
Answer: B — 20 and NaN
Why:
• Regular methods use object this.
• Arrow functions don’t get a this → they inherit from outer scope → this.radius is undefined → result is NaN. ([Medium][2])
🔥 4. Unary plus + logical NOT
+true;
!'Lydia';
Answer: A — 1 and false
Why:
• +true converts to number → 1.
• 'Lydia' is truthy → ! makes it false. ([Medium][2])
🔥 5. Property access with objects
const bird = { size: 'small' };
const mouse = { name: 'Mickey', small: true };
Answer: D — All of them are valid
Why:
• mouse.bird.size ❌ actually invalid because bird isn’t a property of mouse.
However — bracket lookups like mouse[bird.size] or mouse[bird["size"]] resolve to mouse['small']. ([Medium][1])
🔥 6. Objects reference
let c = { greeting: 'Hey!' };
let d;
d = c;
c.greeting = 'Hello';
console.log(d.greeting);
Answer: A — Hello
Why:
Objects are reference types — d points to same object as c. ([Medium][2])
🔥 7. == vs === with primitives & objects
let a = 3;
let b = new Number(3);
let c = 3;
console.log(a == b);
console.log(a === b);
console.log(b === c);
Answer: C — true false false
Why:
• Loose == compares value → true.
• Strict === checks type → false for Number object. ([Medium][2])
🔥 8. Static method on class instance
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor;
return this.newColor;
}
constructor({ newColor = 'green' } = {}) {
this.newColor = newColor;
}
}
const freddie = new Chameleon({ newColor: 'purple' });
console.log(freddie.colorChange('orange'));
Answer: D — TypeError
Why:
Static methods are not accessible on instance. ([Medium][1])
🔥 9. Typos & undefined variables
let greeting;
greetign = {}; // Typo!
console.log(greetign);
Answer: A — {}
Why:
In non-strict mode, this creates a global variable. ([Medium][1])
🔥 10. Functions are objects
function bark() {
console.log('Woof!');
}
bark.animal = 'dog';
Answer: A — Nothing, this is fine!
Why:
Functions are first-class objects — can have properties. ([Medium][1])
🔥 11. Adding methods after instances
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const member = new Person('Lydia', 'Hallie');
Person.getFullName = function() {
return `${this.firstName} ${this.lastName}`;
};
console.log(member.getFullName());
Answer: A — TypeError
Why:
Method is added to constructor, not prototype. ([Medium][1])
🔥 12. Forgetting new
const lydia = new Person('Lydia', 'Hallie');
const sarah = Person('Sarah', 'Smith');
console.log(lydia);
console.log(sarah);
Answer: A — Person { … } and undefined
Why:
Calling constructor without new returns undefined. ([Medium][1])
🔥 13. Event propagation phases
Answer: D — Capturing > Target > Bubbling
Why:
Standard DOM event propagation order. ([Placement Preparation][3])
🔥 14. Prototypes exist for all objects
Answer: A — true
Every object in JS has a prototype chain (except the root). ([Placement Preparation][3])
🔥 15. Number + string
sum(1, '2');
Answer: C — "12"
Why:
String concatenation takes precedence. ([Placement Preparation][3])
🔥 16. Increment operator
let number = 0;
console.log(number++);
console.log(++number);
console.log(number);
Answer: C — 0 2 2
Why:
Postfix vs prefix increment gives different values. ([Placement Preparation][3])
🔥 17. Tagged template literals
getPersonInfo`${person} is ${age} years old`;
Answer: B — array of strings, substitutions
Why:
Tagged templates pass strings array first, then values. ([Placement Preparation][3])
🔥 18. Object literal comparison
Answer: C — “Hmm.. You don't have an age I guess”
Object comparisons always check references, not values. ([Placement Preparation][3])
🔥 19. Rest parameters type
typeof args
Answer: C — "object"
Rest produces an array, and typeof [] is "object". ([Placement Preparation][3])
🔥 20. Strict mode undeclared variable
function getAge() {
'use strict';
age = 21;
}
getAge();
Answer: C — ReferenceError
Strict mode forbids undeclared variables. ([Placement Preparation][3])
🔥 21. eval()
const sum = eval('10*10+5');
Answer: A — 105
eval evaluates arbitrary JS expressions. ([Placement Preparation][3])
🔥 22. sessionStorage lifespan
Answer: B — When the user closes the tab
Session storage is tab-specific. ([Placement Preparation][3])
🔥 23. var redeclaration
var num = 8;
var num = 10;
console.log(num);
Answer: B — 10
var allows redeclaration. ([Placement Preparation][3])
🔥 24. Objects vs Sets
set.has('1');
set.has(1);
Answer: C — true true false true
Object keys are strings; Set distinguishes types. ([Placement Preparation][3])
🔥 25. Duplicate keys in object
const obj = { a: 'one', b: 'two', a: 'three' };
Answer: C — { a: "three", b: "two" }
Duplicate keys overwrite earlier ones. ([Placement Preparation][3])
Top comments (0)