๐ Table of Contents
- Closures, Scope, Hoisting,
this, Prototypes, Event Loop - Asynchronous JavaScript
- Advanced Objects & Memory
- Advanced Functions & ES6+ Features
- Browser & DOM Fundamentals
- Performance & Optimization
- Advanced Types & Equality
- Error Handling & Debugging
- Concurrency & Parallelism
- ESNext & Modern Features
- Patterns & Architecture in JavaScript
๐ฆ Part 1
This section covers Closures, Scope & Hoisting, this, Prototypes, and the Event Loop โ the foundation of almost every frontend interview.
1. ๐ Closures
Definition:
A closure is a function that retains access to its lexical environment (scope chain) even after the outer function has finished executing.
โ Key Points
- JavaScript uses lexical scoping, not dynamic scoping.
- Closures are formed naturally whenever a function is defined inside another.
- Enable data privacy, currying, memoization, event handlers.
โ ๏ธ Gotchas
-
Loop with
var:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// 3, 3, 3 (same var captured)
Fix with let (block-scoped) or IIFE.
Memory leaks:
Closures capturing large objects (like DOM nodes) can prevent garbage collection.Debugging pain:
DevTools may show โunexpectedโ retained variables due to closures.
๐ก Real-world Bug
function registerHandlers(nodes) {
for (var i = 0; i < nodes.length; i++) {
nodes[i].onclick = () => console.log("Clicked:", i);
}
}
// All handlers print last index!
๐ฏ Interview One-Liner
โA closure is a function with its lexical scope bundled in. It enables encapsulation and callbacks but can cause bugs with loops (
var) and memory leaks if you capture more than needed.โ
2. ๐ฆ Scope & Hoisting
Definition:
Scope defines where variables are accessible. Hoisting means declarations are moved to the top of their scope during compilation.
โ Key Points
-
varโ function-scoped, hoisted & initialized asundefined. -
let/constโ block-scoped, hoisted but uninitialized (Temporal Dead Zone, TDZ). - Function declarations โ fully hoisted with body.
- Function expressions โ behave like variables.
โ ๏ธ Gotchas
- TDZ Example:
console.log(x); // ReferenceError
let x = 10;
- Function in block scope:
if (true) {
function foo() {}
}
foo(); // Works differently in strict vs sloppy mode
- Shadowing:
let x = 1;
{
let x = 2;
console.log(x); // 2 (outer x hidden)
}
๐ Quick Table
| Keyword | Scope | Hoisting | Default Init |
|---|---|---|---|
var |
Function | Yes | undefined |
let |
Block | Yes | TDZ (error) |
const |
Block | Yes | TDZ (error) |
| Function | Function | Yes (with body) | - |
๐ฏ Interview One-Liner
โDeclarations are hoisted.
varhoists withundefined;let/consthoist into the TDZ; functions hoist with their body. Thatโs why accessing aletbefore declaration throws, whilevargives undefined.โ
3. ๐งญ The this Keyword
Definition:
this is determined by the call site, not the definition.
โ
Rules of this Binding (Precedence)
-
new binding โ
new Foo() -
explicit binding โ
call,apply,bind -
implicit binding โ
obj.method() -
default binding โ global (window) or
undefined(strict mode)
โ ๏ธ Gotchas
- Losing context:
const obj = { x: 10, f() { console.log(this.x); } };
setTimeout(obj.f, 0); // undefined (lost `this`)
-
Arrow functions: capture lexical
this, cannot be rebound. - bind + call combo:
function f() { console.log(this.x); }
const bound = f.bind({ x: 1 });
bound.call({ x: 2 }); // still 1 (bind wins)
๐ Quick Table
| Call Type |
this Value |
|---|---|
| Global fn (non-strict) | window |
| Global fn (strict) | undefined |
Method call obj.fn()
|
obj |
new Fn() |
New instance |
| Bound fn | Bound object |
| Arrow fn | Lexical scope |
๐ฏ Interview One-Liner
โ
thisis set at call time, not definition. Precedence is:new> explicit (bind) > implicit (object call) > default (global/undefined). Arrow functions inheritthislexically.โ
4. ๐งฉ Prototypes & Inheritance
Definition:
Objects inherit properties via the prototype chain ([[Prototype]]).
โ Key Points
-
Object.create(proto)โ creates object withprotoas prototype. - Functions have a
.prototypeused when called withnew. - Property lookup climbs prototype chain.
โ ๏ธ Gotchas
- Modifying
.prototypeafter instances exist โ they wonโt see changes. - Shadowing: own property hides prototype property.
- Deep prototype chains slow lookups.
Code Example
function Animal(name) { this.name = name; }
Animal.prototype.speak = function() { console.log(this.name + " makes noise"); }
const dog = new Animal("Rex");
dog.speak(); // "Rex makes noise"
console.log(dog.__proto__ === Animal.prototype); // true
๐ฏ Interview One-Liner
โObjects inherit via prototypes. If a property isnโt found, JS looks up the chain. Constructors set their
.prototypeas the prototype of new instances.โ
5. โณ Event Loop & Concurrency
Definition:
The event loop coordinates execution: it runs the call stack, then processes the task queues (macrotasks and microtasks).
โ Key Points
- Macrotasks: setTimeout, setInterval, I/O.
- Microtasks: Promises, MutationObserver, queueMicrotask.
- After each macrotask, the loop drains all microtasks.
โ ๏ธ Gotchas
-
setTimeout(fn, 0)is not immediate โ runs after microtasks. -
Promise.thenalways executes before timeouts. - In Node.js,
process.nextTickruns before microtasks. - Nested promises keep chaining microtasks โ possible starvation.
Code Example
console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");
// Output: A, D, C, B
๐ Execution Order
- Run call stack
- Drain microtask queue
- Run next macrotask
- Repeat
๐ฏ Interview One-Liner
โThe event loop runs stack โ microtasks โ macrotasks. Thatโs why
Promise.thencallbacks run beforesetTimeout(fn, 0).โ
๐ฆ Asynchronous JavaScript
1. โฑ๏ธ Timers (setTimeout, setInterval)
Definition:
setTimeout(fn, delay) schedules a function once after delay; setInterval(fn, delay) repeats at intervals.
โ Key Points
- Actual delay is minimum โ not guaranteed exact.
- Nested timers can be throttled by browsers (clamp to โฅ4ms after many calls, 1000ms when tab inactive).
-
clearTimeout/clearIntervalcancel scheduled tasks.
โ ๏ธ Gotchas
-
setTimeout(fn, 0)runs after all microtasks (not immediate). - Long-running tasks block timers (since JS is single-threaded).
-
setIntervalcan drift โ better to use recursivesetTimeoutfor accuracy.
Example
setTimeout(() => console.log("timeout"), 0);
Promise.resolve().then(() => console.log("promise"));
// Output: promise, timeout
๐ฏ Interview One-Liner
โTimers schedule macrotasks.
setTimeout(fn, 0)isnโt immediate โ it runs after microtasks. For precise intervals, recursivesetTimeoutis safer thansetInterval.โ
2. ๐ Promises
Definition:
A Promise is an object representing the eventual result of an async operation.
โ Key Points
- States: pending โ fulfilled (resolved) / rejected.
-
.thenand.catchreturn new promises โ enable chaining. - Handlers are always async (enqueued as microtasks).
โ ๏ธ Gotchas
- Unhandled rejection:
Promise.reject("err");
// Without .catch โ unhandled rejection warning
-
.thenhandlers always async:
Promise.resolve().then(() => console.log("then"));
console.log("sync");
// sync, then
- Multiple
.thenon the same promise all execute independently. - Returning a promise inside
.thenflattens it (automatic chaining).
Example
Promise.resolve(1)
.then(x => x + 1)
.then(x => Promise.resolve(x + 1))
.then(console.log); // 3
๐ฏ Interview One-Liner
โPromises represent async results.
.thenhandlers are always microtasks, so they run before timers. Returning a promise in.thenflattens the chain.โ
3. โก async / await
Definition:
Syntactic sugar over promises. async functions return promises; await pauses until promise settles.
โ Key Points
-
awaitonly works insideasyncfunctions (or top-level in modules). - Execution is split โ code after
awaitruns in a microtask. - Parallelize with
Promise.allto avoid serial awaits.
โ ๏ธ Gotchas
-
awaitinside loops โ serial execution (slow).
for (const u of users) {
await fetch(u); // slow
}
await Promise.all(users.map(u => fetch(u))); // fast
-
try/catchis needed โawaitthrows on rejection. - Mixing
awaitwith non-promises just wraps inPromise.resolve.
Example
async function f() {
console.log("A");
await Promise.resolve();
console.log("B");
}
f();
console.log("C");
// Output: A, C, B
๐ฏ Interview One-Liner
โ
async/awaitis syntax sugar over promises.awaitpauses execution and resumes in a microtask. Using it inside loops serializes calls โ usePromise.allfor parallelism.โ
4. ๐๏ธ Generators & Async Generators
Definition:
Generators (function*) are functions that can pause and resume using yield. Async generators use for await...of.
โ Key Points
- Generators return an iterator with
.next(). - Useful for building custom async workflows (before promises).
-
colibrary + generators โ pre-async/awaitasync management.
โ ๏ธ Gotchas
- Generators donโt manage async by themselves; must yield promises and have a runner.
- Async generators (
async function*) combine promises with iteration.
Example
function* gen() {
yield 1;
yield 2;
}
const g = gen();
console.log(g.next()); // { value: 1, done: false }
๐ฏ Interview One-Liner
โGenerators pause with
yieldand resume later. Theyโre useful for async flow control, but in modern JS,async/awaitreplaces most generator use cases.โ
5. โณ Debounce & Throttle
Definition:
Patterns for rate-limiting function execution.
- Debounce: wait until no calls happen for X ms. (Good for search input).
- Throttle: allow one call per X ms. (Good for scroll/resize).
Example
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
function throttle(fn, delay) {
let last = 0;
return (...args) => {
const now = Date.now();
if (now - last >= delay) {
fn(...args);
last = now;
}
};
}
๐ฏ Interview One-Liner
โDebounce delays execution until events stop; throttle limits execution to once per interval. Debounce is for inputs, throttle for continuous events like scroll.โ
6. ๐จ requestAnimationFrame (rAF)
Definition:
requestAnimationFrame(callback) schedules a callback before the next repaint (~16.6ms at 60fps).
โ Key Points
- More efficient than
setTimeoutfor animations. - Pauses when tab is inactive (better for performance).
- Ideal for smooth visual updates.
โ ๏ธ Gotchas
- Doesnโt guarantee 60fps โ depends on device refresh rate.
- Can be canceled with
cancelAnimationFrame(id).
Example
function animate() {
// draw frame
requestAnimationFrame(animate);
}
animate();
๐ฏ Interview One-Liner
โ
requestAnimationFrameruns a callback before the next repaint. Itโs optimized for animations and pauses in inactive tabs.โ
7. ๐งต Web Workers
Definition:
Web Workers run JS in background threads, off the main event loop.
โ Key Points
- Communicate via
postMessage(structured clone). - No DOM access inside workers.
- Good for CPU-heavy tasks.
โ ๏ธ Gotchas
- Serialization overhead in
postMessage. - SharedArrayBuffer needed for true shared memory.
- Not supported in all contexts (e.g., some cross-origin iframes).
Example
// worker.js
self.onmessage = e => {
self.postMessage(e.data * 2);
};
// main.js
const worker = new Worker("worker.js");
worker.onmessage = e => console.log("Result:", e.data);
worker.postMessage(10); // Result: 20
๐ฏ Interview One-Liner
โWeb Workers move heavy computation off the main thread. They communicate via messages, but canโt access the DOM.โ
๐ฆ Advanced Objects & Memory
1. ๐งน Garbage Collection (GC)
Definition:
JavaScript uses automatic garbage collection โ freeing memory for objects that are no longer reachable.
โ Key Points
-
Reachability = if an object can be accessed via a reference chain from a root (e.g.
windowor stack). - Common GC strategy: Mark & Sweep.
- Circular references are fine if unreachable from root.
โ ๏ธ Gotchas
-
Accidental leaks:
- Global variables (
window.leak = obj). - Closures holding large structures.
- Detached DOM nodes retained in memory.
- Global variables (
Timers / event listeners: If not cleared, they keep references alive.
Example
let el = document.getElementById("btn");
el.onclick = () => console.log("clicked");
// If `el` removed from DOM but reference stays in closure โ leak
๐ฏ Interview One-Liner
โGC frees unreachable memory. Leaks usually happen via globals, closures, or dangling DOM references, not because of circular references.โ
2. ๐๏ธ Symbols
Definition:
Symbol() creates a unique primitive identifier.
โ Key Points
- Never equal to another symbol, even with same description.
- Used for non-colliding property keys.
-
Symbol.for(key)reuses a global registry symbol. - Built-in symbols customize behavior (
Symbol.iterator,Symbol.toStringTag).
โ ๏ธ Gotchas
-
for...inandObject.keysignore symbols. Must useObject.getOwnPropertySymbols. - JSON.stringify ignores symbols.
Example
const id = Symbol("id");
const obj = { [id]: 123 };
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(id)]
๐ฏ Interview One-Liner
โSymbols are unique identifiers, often used as hidden object keys or to customize built-in behaviors. Theyโre ignored by JSON and normal enumeration.โ
3. ๐๏ธ WeakMap & WeakSet
Definition:
Weak collections hold weak references to objects โ allowing GC when there are no other references.
โ Key Points
- WeakMap: keys must be objects, values arbitrary.
- WeakSet: stores objects, prevents duplicates.
- Entries are not enumerable (no
size, no iteration).
โ ๏ธ Gotchas
- Canโt inspect contents โ intentionally opaque.
- Useful for private data or DOM element caching.
Example
let wm = new WeakMap();
let obj = {};
wm.set(obj, "secret");
console.log(wm.get(obj)); // "secret"
obj = null; // entry auto-removed when GC runs
๐ฏ Interview One-Liner
โWeakMap/WeakSet hold weak references โ objects can be GCโd even if theyโre keys. Theyโre ideal for caching and private data without leaks.โ
4. ๐ Property Descriptors
Definition:
Every property has a descriptor object with attributes:
valuewritableenumerable-
configurable(orget/setfor accessors).
โ Key Points
-
Object.definePropertycontrols property behavior. -
enumerablecontrols visibility in loops. -
configurableprevents deletion or redefinition. - Non-writable prevents assignment.
โ ๏ธ Gotchas
- Default attributes:
falseif defined viadefineProperty. - Freezing (
Object.freeze) sets allwritable=false, configurable=false.
Example
const obj = {};
Object.defineProperty(obj, "x", {
value: 42,
writable: false,
enumerable: true,
configurable: false
});
obj.x = 100; // ignored in strict mode โ TypeError
๐ฏ Interview One-Liner
โProperty descriptors let you control attributes like writable, enumerable, configurable. Theyโre the foundation of
Object.freezeand getters/setters.โ
5. ๐ต๏ธ Proxy & Reflect
Definition:
Proxy allows you to intercept operations on objects. Reflect provides low-level methods that mirror default behavior.
โ Key Points
- Handlers (traps):
get,set,has,deleteProperty,apply,construct. -
Reflectensures correct forwarding (avoids reinventing default behavior). - Used for logging, validation, virtualization, reactive systems (Vue3 uses Proxy).
โ ๏ธ Gotchas
- Proxies can slow performance if overused.
- Can break identity expectations (
obj === proxyis false). - Some operations (like private fields) are not trap-able.
Example
const obj = { a: 1 };
const proxy = new Proxy(obj, {
get(target, prop) {
console.log("get", prop);
return target[prop];
}
});
console.log(proxy.a); // logs: get a โ 1
๐ฏ Interview One-Liner
โProxies wrap objects with traps for operations like get/set.
Reflectprovides the default behavior to forward calls. Proxies power modern reactivity systems.โ
6. ๐ง Immutability Tricks
Definition:
JavaScript objects are mutable by default. Immutability ensures predictable state (important in React/Redux).
โ Key Points
-
Object.freezeโ prevents modifications. -
Object.sealโ prevents adding/removing props, but can update values. -
Object.preventExtensionsโ prevents new props, but allows edits/deletes. - Deep immutability requires recursion or libraries (
immer).
โ ๏ธ Gotchas
- Freeze is shallow โ nested objects still mutable.
- Frozen objects are still extensible by changing prototype unless explicitly blocked.
Example
const obj = Object.freeze({ x: 1, y: { z: 2 } });
obj.x = 10; // ignored
obj.y.z = 20; // allowed (nested not frozen)
๐ฏ Interview One-Liner
โObjects are mutable by default.
freeze/seal/preventExtensionsrestrict changes, but only shallowly. For deep immutability, you need recursion or libraries like Immer.โ
๐ฆ Advanced Functions & ES6+ Features
1. ๐๏ธ Higher-Order Functions (HOFs)
Definition:
Functions that either take functions as arguments or return functions.
โ Key Points
- Foundation of functional programming.
- Enable:
map,filter,reduce, decorators, middleware. - Encourage immutability + composition.
โ ๏ธ Gotchas
- Passing non-functions โ runtime errors.
- Excessive nesting โ callback hell (before Promises/async).
Example
function withLogging(fn) {
return (...args) => {
console.log("Calling with", args);
return fn(...args);
};
}
const sum = (a, b) => a + b;
const loggedSum = withLogging(sum);
loggedSum(2, 3); // logs args โ 5
๐ฏ Interview One-Liner
โA higher-order function either takes functions as arguments or returns them. They enable abstractions like map, filter, and middleware.โ
2. ๐จ Currying & Partial Application
Definition:
-
Currying: Transforming a function
f(a, b, c)intof(a)(b)(c). - Partial application: Pre-filling some arguments, returning a new function.
โ Key Points
- Used in FP libraries like Lodash, Ramda.
- Helps reusability and function composition.
โ ๏ธ Gotchas
- Over-currying โ unreadable code.
- Currying โ partial application (though related).
Example
const currySum = a => b => c => a + b + c;
currySum(1)(2)(3); // 6
function partial(fn, ...fixed) {
return (...rest) => fn(...fixed, ...rest);
}
const add = (a, b) => a + b;
const add5 = partial(add, 5);
add5(10); // 15
๐ฏ Interview One-Liner
โCurrying breaks a function into unary steps (
f(a)(b)(c)), while partial application pre-fills arguments. Both improve reusability.โ
3. ๐ฆ Modules (ESM vs CommonJS)
Definition:
Modules encapsulate code into reusable files.
โ Key Points
-
CommonJS (CJS): Node.js legacy (
require,module.exports). -
ES Modules (ESM): Modern JS (
import,export). - ESM is statically analyzable โ enables tree-shaking.
- Default exports vs named exports.
โ ๏ธ Gotchas
- Mixing CJS and ESM leads to quirks (
defaultinterop). - ESM is always strict mode.
- Imports are hoisted (run before any other code).
Example
// utils.js
export function add(a, b) { return a + b; }
export default function subtract(a, b) { return a - b; }
// main.js
import subtract, { add } from "./utils.js";
๐ฏ Interview One-Liner
โCommonJS uses require, ES Modules use import/export. ESM is statically analyzable and supports tree-shaking, which is why modern bundlers prefer it.โ
4. โจ Destructuring & Spread/Rest
Definition:
Syntax for unpacking values into variables.
โ Key Points
-
Array destructuring:
[a, b] = arr. -
Object destructuring:
{ x, y } = obj. - Rest: gather leftovers.
- Spread: expand arrays/objects.
โ ๏ธ Gotchas
- Nested destructuring โ
undefinedif property missing. - Default values only apply when property is
undefined, notnull.
Example
const [a, b = 5] = [1];
console.log(a, b); // 1, 5
const { x, y: z } = { x: 10, y: 20 };
console.log(z); // 20
const arr = [1, 2];
const newArr = [...arr, 3]; // [1,2,3]
๐ฏ Interview One-Liner
โDestructuring unpacks arrays/objects, rest gathers leftovers, spread expands. Defaults only trigger on
undefined, notnull.โ
5. ๐งพ Default, Rest, and Named Parameters
โ Key Points
- Default params:
function f(x = 10) { return x; }
f(); // 10
- Rest params: collects extra args โ array.
- Named params: simulated with object destructuring.
โ ๏ธ Gotchas
- Default params are evaluated at call time.
- Rest params differ from
arguments(rest is real array,argumentsis array-like).
๐ฏ Interview One-Liner
โDefault params evaluate at call time, rest params gather extras as a real array, and named params are simulated via object destructuring.โ
6. ๐ Iterators & Iterables
Definition:
An iterator is an object with .next(). An iterable has [Symbol.iterator].
โ Key Points
- Iterables: arrays, strings, maps, sets.
-
for...ofloops over iterables (not plain objects). - Custom iterables by implementing
[Symbol.iterator].
โ ๏ธ Gotchas
- Plain objects arenโt iterable unless you define
[Symbol.iterator]. - Spread
...objworks only if iterable defined.
Example
const iterable = {
*[Symbol.iterator]() {
yield 1; yield 2; yield 3;
}
};
for (const x of iterable) console.log(x);
๐ฏ Interview One-Liner
โIterables implement
[Symbol.iterator], which returns an iterator with.next(). Thatโs why arrays, maps, and sets work withfor...ofand spread.โ
7. ๐ Map, Set, WeakMap, WeakSet
Definition:
Specialized collection types introduced in ES6.
โ Key Points
- Map: key-value pairs, keys can be any type.
- Set: unique values.
- WeakMap/WeakSet: only object keys, weak references (non-enumerable).
โ ๏ธ Gotchas
-
NaNis considered equal to itself in Set. - Map preserves insertion order.
- WeakMap doesnโt prevent GC.
Example
const set = new Set([1, 2, 2, 3]);
console.log(set.size); // 3
const map = new Map();
map.set("a", 1).set({}, 2);
๐ฏ Interview One-Liner
โMap and Set are collections with insertion order preserved. WeakMap/WeakSet hold weak object references, useful for caching without memory leaks.โ
8. ๐งญ ES6+ Extras (that interviewers test)
๐ Template Literals
const name = "Alex";
console.log(`Hello ${name}`);
๐ Tagged Templates
function tag(strings, ...values) {
return strings[0] + values.map(v => v.toUpperCase()).join("");
}
console.log(tag`Hi ${"alex"} and ${"bob"}`); // "Hi ALEXandBOB"
๐ Optional Chaining & Nullish Coalescing
obj?.prop?.nested; // avoids TypeError
val ?? "default"; // only default if null/undefined
๐ฏ Interview One-Liner
โModern JS adds quality-of-life features like template literals, optional chaining (
?.), and nullish coalescing (??). These avoid common boilerplate and bugs.โ
๐ฆ Browser & DOM Fundamentals
1. ๐ฏ Event Delegation
Definition:
Attaching a single event listener on a parent to handle events for multiple child elements via event bubbling.
โ Key Points
- Uses event propagation (capture โ target โ bubble).
- Reduces memory usage (no per-child listeners).
- Works well for dynamic DOM (children added later).
โ ๏ธ Gotchas
-
event.targetvsevent.currentTarget:-
target= actual clicked element. -
currentTarget= element with listener.
-
Some events donโt bubble (e.g.,
blur,focus).
Example
document.getElementById("list").addEventListener("click", e => {
if (e.target.tagName === "LI") {
console.log("Clicked item:", e.target.textContent);
}
});
๐ฏ Interview One-Liner
โEvent delegation attaches a single listener on a parent and relies on bubbling. Itโs efficient for many/dynamic child elements.โ
2. ๐ผ๏ธ Reflow vs Repaint (Performance)
Definition:
- Reflow (layout): Browser recalculates element positions & sizes.
- Repaint: Browser redraws pixels (e.g., color change).
โ Key Points
- Reflow is more expensive than repaint.
- Causes of reflow: DOM changes, style changes, window resize, font load.
- Batch DOM reads/writes to avoid multiple reflows.
โ ๏ธ Gotchas
- Accessing layout properties (
offsetHeight,scrollTop) forces reflow. - Animating
top/lefttriggers layout; animatingtransform/opacityis GPU-optimized.
Example
const el = document.getElementById("box");
el.style.width = "200px"; // triggers reflow
console.log(el.offsetHeight); // forces reflow again (expensive)
๐ฏ Interview One-Liner
โReflow recalculates layout, repaint redraws pixels. Reflow is costly โ optimize by batching DOM changes and animating transform/opacity.โ
3. ๐ณ DOM Traversal & Manipulation
โ Methods
-
getElementById,querySelector,querySelectorAll. -
parentNode,children,nextSibling. - Creating:
document.createElement,appendChild,insertBefore. - Performance: Use DocumentFragment for batch insertions.
โ ๏ธ Gotchas
-
innerHTMLis faster for large inserts but unsafe (XSS risk). -
NodeListvsHTMLCollection:-
NodeListcan be static or live. -
HTMLCollectionis always live.
-
๐ฏ Interview One-Liner
โDOM traversal uses APIs like querySelector, parentNode, and siblings. For performance, batch inserts with DocumentFragment instead of repeated appendChild.โ
4. ๐พ Storage APIs
โ Key Points
-
Cookies:
- 4KB limit.
- Sent with every HTTP request.
- Expiration & domain/path scoped.
-
localStorage:
- 5โ10MB.
- Synchronous API.
- Persistent until cleared.
-
sessionStorage:
- Per-tab/session.
-
IndexedDB:
- Async, NoSQL DB in browser.
- Large storage, structured queries.
โ ๏ธ Gotchas
- localStorage is blocking โ avoid heavy writes in main thread.
- Cookies hurt performance since theyโre sent on every request.
- IndexedDB APIs are clunky (usually use wrapper libraries).
๐ฏ Interview One-Liner
โCookies are for server comms (small, auto-sent), localStorage/sessionStorage for small client-only data, and IndexedDB for large structured storage.โ
5. ๐ Browser Security (CORS, CSRF, XSS)
โ CORS (Cross-Origin Resource Sharing)
- Controls cross-domain requests.
- Server sets
Access-Control-Allow-Origin.
โ CSRF (Cross-Site Request Forgery)
- Malicious site tricks userโs browser into sending authenticated request.
- Prevented with CSRF tokens or SameSite cookies.
โ XSS (Cross-Site Scripting)
- Injected scripts executed in victimโs browser.
- Prevented with escaping, CSP (Content Security Policy).
๐ฏ Interview One-Liner
โCORS controls which origins can access resources, CSRF tricks users into sending unwanted requests, and XSS injects malicious scripts. Fix with headers, tokens, and sanitization.โ
6. โก Service Workers
Definition:
Background scripts that intercept network requests โ enable offline caching, push notifications, background sync.
โ Key Points
- Use Cache API for offline storage.
- Run in their own thread (no DOM access).
- Lifecycle: install โ activate โ fetch.
โ ๏ธ Gotchas
- Require HTTPS.
- Debugging can be tricky (stale workers โ need manual refresh).
- Misuse can cause cache-bloat or stale responses.
Example
self.addEventListener("fetch", e => {
e.respondWith(
caches.match(e.request).then(res => res || fetch(e.request))
);
});
๐ฏ Interview One-Liner
โService workers are background scripts that enable offline caching and network interception. They power PWAs but must be carefully managed to avoid stale caches.โ
7. ๐ Critical Rendering Path (CRP)
Definition:
Steps the browser takes to convert HTML/CSS/JS into pixels.
โ Stages
- Parse HTML โ DOM
- Parse CSS โ CSSOM
- Combine โ Render Tree
- Layout (Reflow)
- Paint (Repaint)
- Composite layers
โ ๏ธ Gotchas
-
Render-blocking: CSS blocks rendering, JS blocks parsing unless
defer/async. - Fonts: FOUT/FOIT issues (Flash of Unstyled/Invisible Text).
๐ฏ Interview One-Liner
โThe CRP is DOM + CSSOM โ render tree โ layout โ paint โ composite. Optimize by deferring scripts, minimizing CSS, and preloading fonts.โ
8. ๐งฉ Resource Loading (async vs defer)
Definition:
Attributes that control how scripts load.
โ Key Points
-
async: downloads in parallel, executes ASAP (order not guaranteed). -
defer: downloads in parallel, executes after HTML parse, preserves order. - Default: blocking (bad for performance).
๐ฏ Interview One-Liner
โUse
deferfor scripts that rely on DOM,asyncfor independent scripts. Default blocking scripts delay parsing and hurt performance.โ
๐ฆ Core JavaScript โ Expert-Level Revision
๐ฆ Performance & Optimization
1. ๐งน Memory Leaks in Frontend
Definition:
A memory leak happens when memory is not released after itโs no longer needed.
โ Common Sources
- Uncleared timers/intervals:
setInterval(() => { /* ... */ }, 1000); // never cleared
- Detached DOM nodes kept in closures or global arrays.
- Event listeners not removed on unmount.
- Global variables and singletons that grow unbounded.
๐ฏ Interview One-Liner
โFrontend leaks often come from forgotten event listeners, timers, or DOM nodes retained in closures. Use cleanup (
clearInterval,removeEventListener) and profiling tools.โ
2. ๐ค Lazy Loading & Code Splitting
Definition:
Splitting bundles into smaller chunks and loading them on demand.
โ Key Points
- Reduces initial load time.
- Implemented with dynamic imports (
import()), route-based splitting. - Use
React.lazy+Suspensefor components.
โ ๏ธ Gotchas
- Too many small chunks โ overhead.
- Network latency can hurt if misconfigured.
๐ฏ Interview One-Liner
โLazy loading reduces initial load by splitting code into chunks. Use
import()orReact.lazy. Balance chunk size to avoid too many round-trips.โ
3. ๐ณ Tree-Shaking
Definition:
Removing unused code during bundling.
โ Key Points
- Works only with ESM (import/export) because itโs statically analyzable.
- Dead code elimination depends on bundler + minifier (Webpack, Rollup, Terser).
โ ๏ธ Gotchas
- Dynamic
require()prevents tree-shaking. - Side-effects in modules can block elimination.
๐ฏ Interview One-Liner
โTree-shaking eliminates unused exports but only works with static ES modules. Avoid dynamic imports and side-effects in libraries.โ
4. โก Web Vitals
Definition:
Googleโs metrics for user-perceived performance.
โ Core Metrics
- LCP (Largest Contentful Paint): load speed (<2.5s).
- FID (First Input Delay): input responsiveness (<100ms).
- CLS (Cumulative Layout Shift): visual stability (<0.1).
- (New) INP (Interaction to Next Paint) replacing FID.
๐ฏ Interview One-Liner
โWeb Vitals measure perceived performance: LCP for load, FID/INP for input, CLS for stability. Optimize via lazy loading, preloading, and reducing JS.โ
5. ๐งพ Async Scheduling (Idle Time)
Definition:
Scheduling work when the browser is idle.
โ Key Points
-
requestIdleCallback(cb)โ runs when browser is idle. - Useful for non-critical background work.
- Fallback to timers for unsupported browsers.
โ ๏ธ Gotchas
- Not guaranteed to run (if browser never idle).
- Time budget limited (~50ms).
๐ฏ Interview One-Liner
โ
requestIdleCallbacklets you run background work without blocking the main thread, but it may not fire on busy pages.โ
6. ๐ฏ Preload, Prefetch, DNS Prefetch
โ Key Points
- Preload: critical resources needed soon.
- Prefetch: resources likely needed in future navigation.
- DNS-prefetch: resolve domain names early.
Example
<link rel="preload" href="hero.jpg" as="image" />
<link rel="prefetch" href="/next-page.js" />
<link rel="dns-prefetch" href="//cdn.example.com" />
๐ฏ Interview One-Liner
โPreload fetches critical resources now, prefetch loads likely future ones, DNS-prefetch resolves domains early.โ
7. ๐ฆ Bundling Strategies
- Monolithic bundle โ fast for small apps, bad for scale.
- Code-splitting โ route-level chunks.
- Micro-frontends โ separate bundles per domain (federation).
- CDN caching โ cache chunks by content hash.
๐ฏ Interview One-Liner
โBundle strategy depends on scale. Use route-based code splitting, cache chunks with hashes, and avoid giant monolithic bundles.โ
8. ๐๏ธ Rendering Performance Tips
- Minimize reflows (batch DOM changes).
- Use transform/opacity for animations.
- Virtualize large lists (e.g.,
react-window). - Debounce resize/scroll listeners.
๐ฏ Interview One-Liner
โReflows are expensive โ batch DOM updates, use transform/opacity for animations, and virtualize long lists.โ
๐ฆ Core JavaScript โ Expert-Level Revision
๐ฆ Advanced Types & Equality
1. ๐ Truthy & Falsy Values
Definition:
When converted to a boolean (e.g., in if conditions), some values are considered truthy or falsy.
โ Falsy Values (only 7!)
false-
0,-0 -
""(empty string) nullundefinedNaN
Everything else โ truthy (including "0", [], {}, Infinity).
โ ๏ธ Gotchas
if ("0") console.log("runs"); // runs (string "0" is truthy)
if ([]) console.log("runs"); // runs (empty array is truthy)
if ({}) console.log("runs"); // runs (empty object is truthy)
๐ฏ Interview One-Liner
โOnly 7 values are falsy: false, 0, -0, "", null, undefined, NaN. Everything else is truthy โ even empty arrays/objects.โ
2. ๐ == vs ===
Definition:
-
===(strict equality): no type coercion. -
==(loose equality): allows coercion.
โ Rules (selected weird ones)
0 == false // true
"" == false // true
null == undefined // true
[] == false // true ( [] โ "" โ 0 )
[] == ![] // true ( [] == false )
[1] == 1 // true ([1].toString() โ "1")
[1,2] == "1,2" // true
โ ๏ธ Gotchas
-
NaN == NaNโ false (NaN is never equal to itself). -
nullonly equalsundefined(and itself). -
0 == []is true, but0 == {}is false.
๐ฏ Interview One-Liner
โ
===checks value + type, no coercion.==coerces and has weird rules:null == undefinedonly, arrays convert to strings, and NaN never equals itself.โ
3. ๐งพ Special Numbers: NaN, Infinity, -0
โ NaN
- Not equal to itself:
NaN === NaNโ false. - Use
Number.isNaN()(better thanisNaN). -
isNaN("foo")โ true (coerces to NaN).
โ Infinity
-
1 / 0โInfinity. -
-1 / 0โ-Infinity.
โ -0
- JS has two zeros:
0and-0. -
0 === -0โ true. - But
1 / 0 === Infinity,1 / -0 === -Infinity.
๐ฏ Interview One-Liner
โJS has two zeros: +0 and -0. They compare equal with
===, but divide by them to get ยฑInfinity. NaN is never equal to itself.โ
4. ๐๏ธ Object.is
Definition:
Like === but fixes edge cases:
โ Rules
Object.is(NaN, NaN); // true
Object.is(0, -0); // false
Object.is(5, 5); // true
Object.is({}, {}); // false (different refs)
๐ฏ Interview One-Liner
โ
Object.isis like strict equality but distinguishes -0 and +0, and treats NaN as equal to itself.โ
5. ๐ฆ Primitive vs Object Wrappers
Definition:
Primitives (string, number, boolean, symbol, bigint, null, undefined) have object wrappers for method access.
โ Examples
"hello".toUpperCase(); // works because JS boxes into String object
new String("hello"); // object wrapper
typeof "hello"; // "string"
typeof new String("hi"); // "object"
โ ๏ธ Gotchas
-
new Boolean(false)is truthy (object is always truthy). - Comparing primitive vs object:
"hi" === new String("hi"); // false
"hi" == new String("hi"); // true (coerces)
๐ฏ Interview One-Liner
โPrimitives auto-box into wrappers (e.g., 'hi'.toUpperCase()). But wrapper objects (
new String) are truthy and behave differently โ avoid them.โ
6. ๐งฉ Typeof, instanceof, and Array.isArray
โ typeof
-
typeof nullโ"object"(bug since JS 1.0). -
typeof NaNโ"number". -
typeof function() {}โ"function".
โ instanceof
- Checks prototype chain.
- Works across inheritance.
- Fails across iframes (different globals).
โ Array.isArray
- Safest way to check arrays (cross-realm safe).
Example
[] instanceof Array; // true
[] instanceof Object; // true
Array.isArray([]); // true
typeof null; // "object"
๐ฏ Interview One-Liner
โ
typeof nullis 'object' (legacy bug).instanceofchecks prototype chains but breaks across realms. UseArray.isArrayto check arrays safely.โ
7. ๐งฎ Type Conversion (Explicit vs Implicit)
โ Explicit
-
Number("42")โ 42 -
String(123)โ "123" -
Boolean(0)โ false
โ Implicit (coercion)
-
1 + "2"โ "12" (string concatenation). -
1 - "2"โ -1 (string โ number). -
[] + []โ "" (empty string). -
[] + {}โ "[object Object]". -
{} + []โ 0 (parsed as block + array).
โ ๏ธ Gotchas
[] == ![]; // true
// [] -> "" -> 0, ![] -> false -> 0
๐ฏ Interview One-Liner
โType coercion is implicit conversion. Addition prefers strings, subtraction prefers numbers. Weird cases like [] + {} = '[object Object]' are from toString/valueOf conversions.โ
๐ฆ Core JavaScript โ Expert-Level Revision
๐ฆ Error Handling & Debugging
1. โ ๏ธ try / catch / finally
Definition:
Mechanism for handling runtime exceptions.
โ Key Points
-
catchhandles synchronous errors in thetryblock. -
finallyalways executes (even if return/throw in try/catch). - Errors bubble up if unhandled.
โ ๏ธ Gotchas
try {
throw new Error("boom");
} catch (e) {
return "handled";
} finally {
return "finally"; // overrides catch return
}
๐ฏ Interview One-Liner
โ
finallyalways runs and overrides return values. Errors bubble up unless caught.โ
2. ๐ธ๏ธ Error Types in JavaScript
โ Built-in Error Objects
-
Errorโ base class. -
SyntaxErrorโ invalid syntax (only at parse time). -
ReferenceErrorโ accessing undeclared variable. -
TypeErrorโ invalid operation (e.g., calling non-function). -
RangeErrorโ out-of-range numbers (e.g., invalid array length). -
URIErrorโ malformed URI inencodeURI/decodeURI. -
EvalErrorโ legacy, rarely used.
Example
try {
JSON.parse("{ invalid }");
} catch (e) {
console.log(e instanceof SyntaxError); // true
}
๐ฏ Interview One-Liner
โJS has typed errors: Syntax, Reference, Type, Range, URI. Most common in practice: TypeError and ReferenceError.โ
3. ๐ ๏ธ Custom Errors
Definition:
Extend the Error class for domain-specific errors.
Example
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
throw new ValidationError("Invalid input");
๐ฏ Interview One-Liner
โCustom errors extend Error and set a name for better debugging.โ
4. โก Async Error Handling
โ Promises
fetch("bad-url")
.then(res => res.json())
.catch(err => console.error("Caught:", err));
-
.catch()handles errors in promise chain. - Uncaught rejections trigger
unhandledrejectionevent.
โ async/await
async function getData() {
try {
await fetch("bad-url");
} catch (err) {
console.error("Caught:", err);
}
}
- Must wrap
awaitintry/catch. - Rejections not caught will bubble like exceptions.
๐ฏ Interview One-Liner
โPromise errors bubble until caught. In async/await, use try/catch around awaits. Unhandled rejections trigger a global event.โ
5. ๐ Global Error Handling
โ Browser
window.onerror = (msg, url, line, col, err) => {
console.error("Global error:", msg, err);
};
window.onunhandledrejection = e => {
console.error("Unhandled rejection:", e.reason);
};
โ Node.js
process.on("uncaughtException", err => { ... });
process.on("unhandledRejection", err => { ... });
โ ๏ธ Gotchas
- Donโt rely on global handlers as the only mechanism โ theyโre last resort.
- Use for logging/alerting in production.
๐ฏ Interview One-Liner
โGlobal error handlers (
window.onerror,onunhandledrejection) are safety nets โ good for logging, but not a replacement for local handling.โ
6. ๐งญ Debugging Techniques
โ Tools
-
console.*(log, warn, error, table, dir). -
debuggerkeyword (pauses execution in DevTools). - Source maps (map minified code to original).
โ Advanced
- Performance profiling (DevTools Performance tab).
- Memory profiling (heap snapshots, allocation timelines).
- Break on DOM mutation.
๐ฏ Interview One-Liner
โUse console, debugger, and source maps for debugging. For perf/memory, use DevTools profiling and heap snapshots.โ
7. ๐ Best Practices for Error Handling
- Fail fast, fail safe โ throw early, recover gracefully.
- Donโt swallow errors (
catch(e){}with empty body). - Normalize errors (consistent structure across app).
- Log with context (user action, environment).
- Avoid throwing strings, always
throw new Error(...). - Separate expected errors (validation) from unexpected ones (bugs).
๐ฏ Interview One-Liner
โBest practice: never swallow errors, always throw Error objects, separate expected from unexpected, and log with context.โ
๐ฆ Core JavaScript โ Expert-Level Revision
๐ฆ Concurrency & Parallelism
1. ๐งต Single-Threaded Model
Definition:
JavaScript executes on a single thread (the call stack) with concurrency simulated via the event loop.
โ Key Points
- JS canโt run two functions truly in parallel on the main thread.
- Concurrency = overlapping tasks (via async callbacks).
- Parallelism = tasks literally executing at the same time (needs threads/workers).
โ ๏ธ Gotchas
- Long-running tasks block UI โ โfrozen pageโ.
- Async doesnโt mean parallel (Promises still run on one thread).
๐ฏ Interview One-Liner
โJavaScript is single-threaded; concurrency comes from the event loop, but real parallelism requires workers.โ
2. โณ Concurrency via Event Loop
Definition:
The event loop interleaves tasks from macrotask & microtask queues.
โ Key Points
- Concurrency = cooperative multitasking.
- No two JS functions run at the same instant on the same thread.
Example
setTimeout(() => console.log("timer"), 0);
Promise.resolve().then(() => console.log("promise"));
// Output: promise, timer
๐ฏ Interview One-Liner
โConcurrency in JS is managed by the event loop โ tasks interleave but donโt run truly in parallel.โ
3. โก Parallelism via Web Workers
Definition:
Web Workers run JS in background threads separate from the main UI thread.
โ Key Points
- Communicate via
postMessage(structured cloning). - No direct DOM access.
- Useful for CPU-heavy tasks.
โ ๏ธ Gotchas
- Serialization overhead for large messages.
- No shared state by default (copy-on-message).
- Debugging workers is harder than main thread code.
Example
// worker.js
self.onmessage = e => self.postMessage(e.data * 2);
// main.js
const w = new Worker("worker.js");
w.onmessage = e => console.log(e.data);
w.postMessage(10); // 20
๐ฏ Interview One-Liner
โWeb Workers provide real parallelism by running JS in separate threads, but canโt touch the DOM and communicate only via messages.โ
4. ๐งฉ SharedArrayBuffer & Atomics
Definition:
APIs for shared memory and low-level synchronization between workers.
โ Key Points
-
SharedArrayBuffer: allows multiple threads to view/edit same memory. -
Atomics: provides atomic operations (safe increments, waits, notifications). - Enables building locks, semaphores, and concurrent data structures in JS.
โ ๏ธ Gotchas
- Very advanced โ rarely used directly, but underpins WebAssembly multithreading.
- Security concerns โ disabled after Spectre/Meltdown, re-enabled with stricter cross-origin isolation.
Example
const buffer = new SharedArrayBuffer(4);
const arr = new Int32Array(buffer);
Atomics.store(arr, 0, 42);
console.log(Atomics.load(arr, 0)); // 42
๐ฏ Interview One-Liner
โSharedArrayBuffer + Atomics let workers share memory and coordinate safely. Itโs how JS supports real multithreading in WebAssembly.โ
5. ๐งฎ Parallelism in Node.js
Definition:
Node is single-threaded per process, but offers parallelism.
โ Key Points
- Worker Threads (since Node 10.5) โ parallel JS execution.
- Child Processes โ true OS-level processes.
- Cluster Module โ multiple processes sharing load.
- libuv threadpool โ parallelize I/O and certain CPU tasks (crypto, fs).
๐ฏ Interview One-Liner
โNode achieves parallelism with worker threads, child processes, or libuvโs threadpool โ though the main JS thread is single.โ
6. ๐๏ธ Practical Uses of Parallelism
- Image processing in background via workers.
- Large JSON parsing โ offload to worker to avoid UI freeze.
- Concurrent fetch requests โ concurrency (not parallelism).
- WebAssembly with threads โ real CPU parallelism.
๐ฆ Core JavaScript โ Expert-Level Revision
๐ฆ ESNext & Modern Features
1. ๐ข BigInt
Definition:
A primitive type for arbitrarily large integers.
โ Key Points
- Append
nโ123n. - Canโt mix with normal
Numberwithout explicit conversion. - No precision loss for huge numbers.
โ ๏ธ Gotchas
2n + 3; // TypeError (canโt mix BigInt and Number)
Number(2n) === 2; // true
๐ฏ Interview One-Liner
โBigInt represents integers beyond Numberโs 2^53-1 limit. You canโt mix it with Number โ must explicitly convert.โ
2. ๐งฉ Optional Chaining (?.)
Definition:
Safe property access without throwing if intermediate is null/undefined.
โ Key Points
- Short-circuits if value is null/undefined.
- Works with properties, function calls, array indexes.
Example
const user = {};
console.log(user.profile?.email); // undefined, not error
console.log(user.getName?.()); // undefined
๐ฏ Interview One-Liner
โOptional chaining avoids errors by short-circuiting on null/undefined. It works for props, calls, and arrays.โ
3. ๐ฐ Nullish Coalescing (??)
Definition:
Provides a fallback only for null/undefined, not falsy values.
โ Key Points
0 || 42; // 42
0 ?? 42; // 0
"" || "x"; // "x"
"" ?? "x"; // ""
๐ฏ Interview One-Liner
โ
??differs from||by treating only null/undefined as missing. Falsy values like 0 and '' are kept.โ
4. ๐ Top-Level await
Definition:
Allows await at the top level of ES modules.
โ Key Points
- Only allowed in ES modules (
type="module"). - Blocks module evaluation until awaited promise resolves.
Example
// top-level-await.js
const data = await fetch("/api").then(r => r.json());
console.log(data);
๐ฏ Interview One-Liner
โTop-level await lets you use await outside functions in ES modules, pausing module execution until resolved.โ
5. โป๏ธ WeakRefs & FinalizationRegistry
Definition:
APIs to reference objects without preventing GC.
โ WeakRef
-
new WeakRef(obj)โ creates weak reference. -
.deref()returns object if still alive, else undefined.
โ FinalizationRegistry
- Lets you run cleanup after object GC (non-deterministic).
โ ๏ธ Gotchas
- Unreliable for program logic โ GC is unpredictable.
- Intended for caches, not control flow.
Example
let obj = { value: 123 };
const weak = new WeakRef(obj);
obj = null; // eligible for GC
console.log(weak.deref()); // maybe object, maybe undefined later
๐ฏ Interview One-Liner
โWeakRefs allow GCโd objects to be referenced weakly, and FinalizationRegistry lets you clean them up. Use for caches, not program logic.โ
6. ๐ Temporal API (Proposal Stage 3)
Definition:
New Date/Time API to replace Date (which is broken).
โ Key Points
- Immutable, time zone aware, clear APIs.
- Objects:
PlainDate,PlainTime,ZonedDateTime,Duration. - Fixes DST bugs, leap second issues.
Example
import { Temporal } from "@js-temporal/polyfill";
const today = Temporal.Now.plainDateISO();
console.log(today.add({ days: 1 }).toString());
๐ฏ Interview One-Liner
โTemporal is the modern Date/Time API: immutable, time-zone aware, and accurate. Itโs the future replacement for JS Date.โ
7. ๐ฆ Dynamic Import
Definition:
import() loads modules dynamically at runtime.
โ Key Points
- Returns a promise.
- Enables conditional/lazy loading.
- Used for code-splitting.
Example
if (condition) {
const mod = await import("./math.js");
mod.add(2, 3);
}
๐ฏ Interview One-Liner
โDynamic import lets you load modules at runtime. It returns a promise, enabling conditional and lazy loading.โ
8. ๐ฏ Logical Assignment Operators
Definition:
Shorthand operators for logical + assignment.
โ Key Points
-
||=assigns if falsy. -
&&=assigns if truthy. -
??=assigns if null/undefined.
Example
let a = null;
a ||= 5; // a = 5
let b = 0;
b ||= 5; // b = 5
b ??= 5; // b = 0 (unchanged)
๐ฏ Interview One-Liner
โLogical assignment operators (||=, &&=, ??=) combine short-circuiting with assignment. Handy for defaults and conditionals.โ
9. ๐งพ Numeric Separators
Definition:
Underscores in numbers for readability.
Example
const big = 1_000_000_000;
console.log(big); // 1000000000
๐ฏ Interview One-Liner
โNumeric separators make large numbers readable, but donโt affect the value.โ
๐ฆ Core JavaScript โ Expert-Level Revision
๐ฆ Patterns & Architecture in JavaScript
1. ๐ฆ Module Pattern
Definition:
Encapsulates private state using closures, exposing only a public API.
โ Key Points
- Common before ES6 modules (
import/export). - Uses IIFEs (Immediately Invoked Function Expressions).
- Prevents polluting global scope.
Example
const Counter = (function () {
let count = 0; // private
return {
inc: () => ++count,
get: () => count,
};
})();
console.log(Counter.inc()); // 1
console.log(Counter.count); // undefined
๐ฏ Interview One-Liner
โThe module pattern hides implementation details with closures and exposes a controlled API. It was the precursor to ES modules.โ
2. ๐๏ธ Observer Pattern
Definition:
One-to-many dependency: when subject changes, observers are notified.
โ Key Points
- Basis for event systems.
- Used in RxJS, MobX, DOM events.
Example
class Subject {
constructor() { this.observers = []; }
subscribe(fn) { this.observers.push(fn); }
notify(data) { this.observers.forEach(fn => fn(data)); }
}
const subject = new Subject();
subject.subscribe(data => console.log("Got:", data));
subject.notify("Hello");
๐ฏ Interview One-Liner
โThe observer pattern lets many listeners react when one subject changes. It underlies events, RxJS, and reactive libraries.โ
3. ๐ก Pub/Sub Pattern
Definition:
Decouples publishers from subscribers via a mediator (event bus).
โ Key Points
- Pub/Sub is like Observer but with a broker in between.
- Subscribers donโt know who published the event.
Example
const bus = {};
bus.events = {};
bus.subscribe = (event, fn) =>
(bus.events[event] = (bus.events[event] || []).concat(fn));
bus.publish = (event, data) =>
(bus.events[event] || []).forEach(fn => fn(data));
bus.subscribe("login", user => console.log("Welcome", user));
bus.publish("login", "Alice");
๐ฏ Interview One-Liner
โPub/Sub decouples producers and consumers with an event bus. Unlike Observer, subscribers donโt directly attach to the subject.โ
4. ๐งโ๐คโ๐ง Singleton Pattern
Definition:
Restricts a class/module to a single instance.
โ Key Points
- Common for global state, config, caches.
- Enforced via closures or static variables.
Example
class Singleton {
constructor() {
if (Singleton.instance) return Singleton.instance;
Singleton.instance = this;
}
}
const a = new Singleton();
const b = new Singleton();
console.log(a === b); // true
๐ฏ Interview One-Liner
โSingleton ensures one instance globally โ useful for config, caches, or logging, but overuse makes testing harder.โ
5. ๐ญ Factory Pattern
Definition:
Function/class that creates objects without exposing the creation logic.
โ Key Points
- Encapsulates instantiation.
- Can return different subclasses depending on arguments.
Example
function createUser(type) {
if (type === "admin") return { role: "admin" };
return { role: "guest" };
}
console.log(createUser("admin"));
๐ฏ Interview One-Liner
โFactory abstracts object creation, returning different variants without exposing constructor details.โ
6. ๐งฉ Prototype Pattern
Definition:
Creates new objects by cloning existing ones.
โ Key Points
- In JS, all objects already inherit via prototypes.
- Object cloning often uses
Object.create(proto).
Example
const animal = { speak() { console.log("Hi"); } };
const dog = Object.create(animal);
dog.speak(); // "Hi"
๐ฏ Interview One-Liner
โPrototype pattern creates objects by cloning existing ones. In JavaScript, itโs built into the language via
Object.create.โ
7. ๐งฎ Functional Patterns (FP in JS)
โ Immutability
- Avoid mutating objects/arrays; use spread or
Object.assign.
โ Function Composition
const compose = (f, g) => x => f(g(x));
const double = x => x * 2;
const square = x => x * x;
console.log(compose(square, double)(3)); // (3*2)^2 = 36
โ
Pipeline (proposed |> operator)
- More readable left-to-right function chaining.
๐ฏ Interview One-Liner
โFP patterns in JS emphasize immutability, pure functions, and composition. Composition allows small functions to build complex logic.โ
8. โ๏ธ Strategy Pattern
Definition:
Encapsulates interchangeable algorithms behind a common interface.
โ Example
class Payment {
setStrategy(strategy) { this.strategy = strategy; }
pay(amount) { this.strategy.pay(amount); }
}
class Paypal { pay(a) { console.log("PayPal:", a); } }
class Stripe { pay(a) { console.log("Stripe:", a); } }
const payment = new Payment();
payment.setStrategy(new Paypal());
payment.pay(100); // PayPal: 100
๐ฏ Interview One-Liner
โStrategy encapsulates interchangeable algorithms, letting you switch behaviors dynamically.โ
9. ๐ต๏ธ Decorator Pattern
Definition:
Adds functionality to objects without modifying them.
โ Key Points
- Popular in React (HOCs).
- In ES, decorator syntax (
@) is in proposal stage.
Example
function withLogging(fn) {
return (...args) => {
console.log("Args:", args);
return fn(...args);
};
}
const sum = (a, b) => a + b;
const loggedSum = withLogging(sum);
loggedSum(2, 3); // Logs args
๐ฏ Interview One-Liner
โDecorator adds behavior to functions or objects without modifying the original โ e.g., React HOCs.โ
10. ๐ธ๏ธ Middleware Pattern
Definition:
Chain of functions where each step can process input and pass to next.
โ Key Points
- Popular in Express.js, Redux.
- Flexible for cross-cutting concerns (logging, auth).
Example
function compose(middleware) {
return function (ctx) {
let i = 0;
function next() {
const fn = middleware[i++];
if (fn) fn(ctx, next);
}
next();
};
}
const fn = compose([
(ctx, next) => { ctx.push("a"); next(); },
(ctx, next) => { ctx.push("b"); next(); }
]);
const arr = [];
fn(arr);
console.log(arr); // ["a","b"]
๐ฏ Interview One-Liner
โMiddleware composes a pipeline of functions where each can act and forward. Used in Express, Redux, Koa.โ
โ Summary (Full Handbook)
This handbook covers expert-level JavaScript concepts in depth:
- Closures, Scope, Hoisting,
this, Prototypes, Event Loop - Asynchronous JavaScript (Timers, Promises, async/await, Generators, Debounce/Throttle, rAF, Workers)
- Advanced Objects & Memory (GC, Symbols, WeakMap/WeakSet, Descriptors, Proxy/Reflect, Immutability)
- Advanced Functions & ES6+ (HOFs, Currying, Modules, Destructuring, Params, Iterables, Map/Set, ES6+)
- Browser & DOM (Event Delegation, Reflow vs Repaint, DOM APIs, Storage, Security, Service Workers, CRP, Loading)
- Performance & Optimization (Leaks, Lazy Loading, Tree-shaking, Web Vitals, Async Scheduling, Bundling, Rendering)
- Advanced Types & Equality (Truthy/Falsy, == vs ===, NaN/-0, Object.is, Wrappers, typeof quirks, Coercion)
- Error Handling & Debugging (try/catch, Error types, Custom errors, Async handling, Global handlers, Debugging)
- Concurrency & Parallelism (Single-threaded model, Event Loop, Workers, SharedArrayBuffer, Node parallelism)
- ESNext & Modern Features (BigInt, Optional Chaining, Nullish, Top-level await, WeakRefs, Temporal, Imports, Operators)
- Patterns & Architecture (Module, Observer, Pub/Sub, Singleton, Factory, Prototype, FP, Strategy, Decorator, Middleware)
Top comments (0)