Core JavaScript Concepts
- Scope and closures — how lexical scoping works and why closures are powerful
- Prototypal inheritance — the prototype chain,
Object.create(), and howclasssyntax maps to prototypes - The event loop — call stack, task queue, microtask queue, and how asynchronous code executes
- Type coercion — implicit vs explicit conversion,
==vs===, and truthy/falsy values
Q1.What are closures in JavaScript? Provide a practical example of when you would use one.
function createCounter() {
let count = 0;
return {
increment: () => ++count,
getCount: () => count
};
}
Here, count is private — it cannot be accessed directly from outside, only through the returned methods.
Common use cases:
• Module patterns for data encapsulation
• Function factories and partial application
• Event handlers that need to remember state
• Memoization and cachingQ2.Explain the JavaScript event loop. How do microtasks and macrotasks differ?
Promise.then() / .catch() / .finally()
• queueMicrotask()
• MutationObserver
Macrotasks (lower priority):
• setTimeout() / setInterval()
• setImmediate() (Node.js)
• I/O operations
• UI rendering events
Key insight: Microtasks are fully drained before the next macrotask runs. This means a Promise.resolve().then() will always execute before a setTimeout(cb, 0), even though both are asynchronous.
Common interview trap:
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
Output: 1, 4, 3, 2Q3.What is prototypal inheritance in JavaScript? How does it differ from classical inheritance?
class keyword is syntactic sugar over prototypes.
How the prototype chain works:
• Every object has an internal [[Prototype]] link (accessible via Object.getPrototypeOf() or __proto__)
• When you access a property on an object, JavaScript walks up the prototype chain until it finds the property or reaches null
• Methods defined on Constructor.prototype are shared across all instances (memory efficient)
Key differences from classical inheritance:
• No classes at the engine level — objects delegate to other objects
• Any object can be a prototype, not just class definitions
• Prototypes are live — adding a method to a prototype instantly makes it available to all instances
Creating inheritance:
• Object.create(proto) — creates a new object with proto as its prototype
• Constructor functions with new — sets prototype automatically
• ES6 class / extends — cleaner syntax, same mechanism underneath
Best practice: Favor composition over deep inheritance chains. Use mixins or object composition for code reuse.ES6+ Features & Modern JavaScript
- Variable declarations —
let,const, and the death ofvar - Arrow functions — lexical
thisbinding and concise syntax - Destructuring and spread — extracting values and merging objects/arrays
- Modules —
import/export, tree-shaking, and dynamic imports - Iterators and generators —
Symbol.iterator,function*, andyield
Q4.What are the differences between var, let, and const? When should you use each?
var — function-scoped (or global if declared outside a function)
• let and const — block-scoped (scoped to the nearest {} block)
Hoisting behavior:
• var — hoisted and initialized to undefined (can be used before declaration without error, but value is undefined)
• let / const — hoisted but NOT initialized (accessing before declaration throws ReferenceError — the Temporal Dead Zone)
Reassignment:
• var and let — can be reassigned
• const — cannot be reassigned, but the value itself can be mutated if it's an object or array
Best practices:
1. Use const by default — signals that the binding won't change
2. Use let only when you need to reassign (loop counters, accumulated values)
3. Never use var in modern code — block scoping prevents entire categories of bugs
Common gotcha:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs: 3, 3, 3 (var is function-scoped)
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs: 0, 1, 2 (let creates new binding per iteration)Async JavaScript Patterns
- Callbacks — the original async pattern, callback hell, and error-first convention
- Promises —
.then()chaining,Promise.all(),Promise.race(),Promise.allSettled() - Async/await — syntactic sugar over Promises, error handling with
try/catch - Concurrent patterns — parallelizing independent operations, controlling concurrency
Q5.Compare Promises with async/await. What are the advantages of each?
.then() and .catch()
• Better for composing multiple async operations with combinators: Promise.all(), Promise.race(), Promise.allSettled()
• Can become hard to read with complex chains (though better than callbacks)
Async/await:
• Makes asynchronous code look synchronous — easier to read and reason about
• Error handling uses standard try/catch blocks instead of .catch()
• Easier to debug — stack traces are cleaner, and you can step through with a debugger
When to use which:
• Use async/await for sequential async operations and when readability matters most
• Use Promise.all() when you need to run independent async operations in parallel
• Combine both: await Promise.all([fetch(url1), fetch(url2)])
Common mistake to avoid:
• Unnecessary sequential awaits:
// Bad — sequential (slow)
const a = await fetchA();
const b = await fetchB();
// Good — parallel (fast)
const [a, b] = await Promise.all([fetchA(), fetchB()]);Q6.What is the difference between Promise.all(), Promise.allSettled(), and Promise.race()?
{status, value/reason} objects
• Use when: you need results from all operations regardless of individual failures (e.g., batch processing where partial success is acceptable)
Promise.race(promises):
• Resolves or rejects as soon as the FIRST promise settles
• Use when: you want the fastest response (e.g., querying multiple redundant servers) or implementing timeouts
Promise.any(promises) (ES2021):
• Resolves when the FIRST promise resolves (ignores rejections)
• Rejects only if ALL promises reject (with an AggregateError)
• Use when: you want the first successful result from multiple attemptsFrequently Asked Questions
Should I learn TypeScript or JavaScript for interviews?
Know JavaScript deeply first — TypeScript is a superset, and most interview questions test core JavaScript concepts. However, if the role involves TypeScript, demonstrating type system knowledge (generics, utility types, discriminated unions) is a strong positive. Many companies let you choose either during coding rounds.
How important are JavaScript frameworks for interviews?
Framework-specific questions (React, Vue, Angular) are typically separate from core JavaScript rounds. However, understanding the underlying JavaScript concepts — closures, the event loop, prototypes, async patterns — is essential regardless of framework. A strong JavaScript foundation makes framework questions much easier.
What level of ES6+ knowledge is expected in 2025?
ES6+ features are no longer 'new' — they are the standard. Interviewers expect fluent use of arrow functions, destructuring, template literals, modules, Promises, async/await, optional chaining, and nullish coalescing. Newer features like Array.at(), structuredClone(), and top-level await are bonus points.
Don't freeze in your next interview
InterviewsUnlocked gives you real-time AI coaching during live interviews — role-tailored answers, follow-up cues, and confidence when you need it most.
Related Resources
React Interview Questions & Answers: Hooks, Patterns, and Performance
Master React interviews with questions covering hooks, component patterns, state management, performance optimization, and Next.js — with detailed expert answers.
Read moreSkills & TechnologiesCSS Interview Questions & Answers: Layout, Design, and Modern Techniques
Master CSS interviews with questions covering Flexbox, Grid, specificity, responsive design, animations, and modern CSS-in-JS approaches with detailed expert answers.
Read moreInterview QuestionsTop Frontend Developer Interview Questions & Answers
Ace your frontend developer interview with questions on JavaScript, React, CSS, web performance, accessibility, and system design with expert answers.
Read moreInterview QuestionsTop Software Engineer Interview Questions & Answers
Prepare for your software engineering interview with expert-crafted questions and detailed answers covering data structures, algorithms, system design, and behavioral topics.
Read moreInterview TipsTechnical Interview Preparation: A 4-Week Plan
A structured 4-week technical interview preparation plan covering data structures, algorithms, system design, and mock interviews with daily schedules.
Read more