🧬 Advanced JavaScript — Prototypes, this, Hoisting & The Event Loop
Senior-level JavaScript concepts: prototype chain, `this` binding, hoisting, event loop, currying, debounce vs throttle. Built to crack the toughest interview rounds.
These are the topics that separate junior from senior JavaScript developers — and they're guaranteed to come up in mid/senior interviews.
🧬 Prototype chain
Every object has a hidden link (__proto__) to another object. Property lookups walk up that chain until found or hitting null.
const arr = [];
arr.__proto__ === Array.prototype; // true
Array.prototype.__proto__ === Object.prototype;// true
Object.prototype.__proto__ === null; // top🎯 `this` — the 5 rules
- Method call —
obj.fn()→ this is obj - Plain call —
fn()→ undefined (strict) or window - new —
new Fn()→ the new instance - call/apply/bind — explicit
- Arrow — inherits from enclosing scope
🔁 Event loop deep cut
One call stack. A microtask queue (Promises, queueMicrotask). A macrotask queue (setTimeout, I/O, UI events). After every macrotask, the engine drains all microtasks before painting or processing the next macrotask.
🍛 Currying
const add = a => b => c => a + b + c;
add(1)(2)(3); // 6⏱️ Debounce vs Throttle
- Debounce: wait until user stops (search input)
- Throttle: at most once per interval (scroll handler)
💻 Code Examples
Debounce — search input
function debounce(fn, ms) {
let t;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn(...args), ms);
};
}
const onSearch = debounce(query => fetch(`/search?q=${query}`), 300);Output:
fetch only fires 300ms after typing stops.
this binding gotcha
const user = {
name: 'Sam',
greet() { return `Hi ${this.name}`; }
};
const g = user.greet;
user.greet(); // 'Hi Sam'
g(); // 'Hi undefined' — lost thisOutput:
Detaching a method loses `this`. Fix with .bind(user) or arrow wrapping.
Prototype chain in action
function Animal(name) { this.name = name; }
Animal.prototype.speak = function() {
return `${this.name} makes a sound`;
};
const dog = new Animal('Rex');
dog.speak(); // 'Rex makes a sound'Output:
speak isn't on dog — it's found via the prototype chain.
⚠️ Common Mistakes
- Confusing prototype with __proto__ — Foo.prototype is what instances inherit; obj.__proto__ is the actual link.
- Using arrow functions for methods that need `this` bound to the object.
- Throttling when you meant to debounce (or vice versa).
- Assuming setTimeout(fn, 0) runs immediately — it waits for the current call stack and microtasks to clear.
🎯 Interview Questions
Real questions asked at top product and service-based companies.
Q1.Explain the prototype chain.Advanced
Every object has a [[Prototype]] reference to another object. When you access a property, JS searches the object, then its prototype, then that prototype's prototype, up to Object.prototype, whose prototype is null. That walk is the prototype chain.
Q2.What is `this` and how is it determined?Advanced
`this` is the execution context of a function call. Rules: method call → object; plain call → undefined/window; new → new instance; call/apply/bind → explicit value; arrow → lexically inherited.
Q3.Explain the event loop.Advanced
JS runs on a single call stack. Async operations are handled by host APIs and put their callbacks in microtask or macrotask queues. The loop: run stack to empty → drain microtasks → take next macrotask → repeat. Render happens between macrotasks.
Q4.Difference between debounce and throttle?Advanced
Debounce delays execution until X ms after the LAST call — good for search-as-you-type. Throttle ensures at most one execution per X ms — good for scroll, resize, mousemove.
Q5.What is currying?Advanced
Transforming a function of N arguments into N nested functions of 1 argument each: `f(a, b, c)` → `f(a)(b)(c)`. Enables partial application and cleaner composition.
Q6.What's the output? `setTimeout(()=>console.log(1),0); Promise.resolve().then(()=>console.log(2)); console.log(3);`Advanced
3, 2, 1. Synchronous logs first, then all microtasks (Promises), then macrotasks (setTimeout).
🧠 Quick Summary
- Prototypes power JS inheritance — classes are sugar over them.
- 5 `this` rules: method, plain, new, call/bind, arrow.
- Event loop drains microtasks fully between macrotasks.
- Debounce = wait until quiet; throttle = rate-limit.
- Currying transforms multi-arg functions into chained single-arg ones.