MindForge
MindForge
DashboardHelp & Support
Dashboard
MindForge

Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
Functions, this, and Binding
Course contents

Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
Browsing without an account — progress is saved in this browser only.Sign in to save it

Functions, this, and Binding

Reading30 min

"Implement bind from scratch" is one of the most reliable whiteboard questions there is, because it forces you to actually understand this-binding mechanics instead of just knowing which method to reach for. This lesson builds call, apply, and bind by hand, then covers three smaller patterns, the in operator, currying, and method chaining, that all lean on the same idea: a function call is just an expression, and what it returns is entirely up to you.

call, apply, bind: three ways to control this

All three answer one question: what should this be inside a function call? call and apply answer it immediately, invoking the function right away with a chosen this. bind answers it lazily: it hands back a new function with this permanently fixed, to be called whenever you're ready.

JavaScript
Function.prototype.myCall = function (context, ...args) {
  context = context || globalThis;
  const fnKey = Symbol('fn'); // a unique key so no existing property gets clobbered
  context[fnKey] = this;
  const result = context[fnKey](...args);
  delete context[fnKey];
  return result;
};

Function.prototype.myApply = function (context, argsArray) {
  context = context || globalThis;
  const fnKey = Symbol('fn');
  context[fnKey] = this;
  const result = argsArray ? context[fnKey](...argsArray) : context[fnKey]();
  delete context[fnKey];
  return result;
};

Function.prototype.myBind = function (context, ...boundArgs) {
  const fn = this;
  return function (...callArgs) {
    if (this instanceof fn) return fn.apply(this, [...boundArgs, ...callArgs]); // called with `new`
    return fn.apply(context, [...boundArgs, ...callArgs]);
  };
};

const obj = { name: 'Nayan' };
function greet(greeting, punctuation) {
  console.log(greeting + ', ' + this.name + punctuation);
}
greet.myCall(obj, 'Hi', '!');        // Hi, Nayan!
greet.myApply(obj, ['Hello', '.']);  // Hello, Nayan.
greet.myBind(obj, 'Hey')('?');       // Hey, Nayan?

Two details in that implementation are exactly what an interviewer probes for. First, myBind is written in terms of apply, not the other way around, because bind's whole job is deferring a call, and once it is finally time to make that call, it needs the same "invoke with this and args" mechanism apply already provides. Second, myCall/myApply attach the function to context under a Symbol key rather than a plain string like "fn", because a string could collide with a real property already on context and silently overwrite it for the duration of the call. A Symbol() can never collide with anything.

The trap worth knowing before it costs you in an interview: none of the three work on arrow functions the way you would expect. Arrow functions have no this of their own; they close over this from whatever scope they were defined in, permanently, at definition time. Calling .call()/.apply()/.bind() on one still runs it, but the context argument is silently ignored. And if bind is called twice, fn.bind(a).bind(b), the first bind wins: fn.bind(a) already hard-locks this to a, so a second .bind(b) on that result can only prepend more arguments; it can never override a this that is already locked in.

Remember: call/apply run the function now. bind hands you a new function to run later. None of the three can override an arrow function's this.

Sign in to try this knowledge check.

The in operator: existence, not truthiness

in checks whether a property exists on an object at all, even if its value is undefined, which is a different question than whether the value is truthy.

JavaScript
const config = { retries: undefined };

if (config.retries) {
  // never runs — undefined is falsy, so this looks like "no retries configured"
}
if ('retries' in config) {
  // runs — the key IS there, it's just explicitly set to undefined
}

config.retries is undefined, which is falsy, so a naive truthiness check reads that as "missing." But the key genuinely exists; it was just deliberately set to undefined. Any falsy-but-present value, 0, "", false, null, undefined, breaks a truthiness check used as an existence check, and in is the one of the three common options (in, hasOwnProperty, truthiness) that answers "does this key exist" and nothing else.

in also walks the prototype chain, the same delegation mechanism the next lesson covers in depth, which is the practical difference between in and hasOwnProperty:

JavaScript
const arr = [1, 2, 3];
console.log('length' in arr);   // true — own property
console.log('push' in arr);     // true — inherited from Array.prototype
console.log(5 in arr);          // false — out of bounds

const user = { name: 'Nayan' };
console.log(user.hasOwnProperty('toString')); // false — inherited, not own
console.log('toString' in user);              // true — in counts inherited too

Object.keys(obj).includes(key) agrees with hasOwnProperty for a normal object literal, since both only look at own, enumerable keys, but the two can diverge for a property explicitly defined with enumerable: false via Object.defineProperty.

Remember: in answers "does this key exist," even if its value is falsy or undefined. Truthiness answers a different question entirely.

Sign in to try this knowledge check.

Currying: one argument at a time

Currying turns a function that takes several arguments into a chain of functions that each take one, returning a new function until every argument has finally arrived.

JavaScript
// Normal
function add(a, b) { return a + b; }
add(2, 3); // 5

// Curried
const add = a => b => a + b;
add(2)(3); // 5

The immediate payoff is partial application: baking in the first argument to get a specialized function back.

JavaScript
const add10 = add(10);
add10(5);  // 15
add10(20); // 30

which makes curried functions natural to chain through .map or a pipe helper:

JavaScript
const multiply = a => b => a * b;
[1, 2, 3].map(multiply(2)); // [2, 4, 6]

const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const process = pipe(add(1), multiply(2), add(10));
process(5); // ((5+1)*2)+10 = 22

Real code rarely hand-writes the nested-arrow form for every function; a generic curry helper auto-curries based on how many arguments the original function declared:

JavaScript
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) return fn(...args);
    return (...more) => curried(...args, ...more);
  };
}

const add3 = curry((a, b, c) => a + b + c);
add3(1)(2)(3);  // 6
add3(1, 2)(3);  // 6 — same destination, arguments just supplied in different-sized groups

Trace add3(1)(2)(3) through the helper: the first call is curried(1). Since fn.length is 3 and only one argument has arrived, it returns a new function still waiting. Calling that with (2) runs curried(1, 2), still short, and returns another waiting function. Calling that with (3) finally runs curried(1, 2, 3), which meets fn.length, so it calls the original fn(1, 2, 3) and returns 6. This is exactly what _.curry does under the hood in Lodash. Across languages, the default varies: Haskell curries every function automatically; Scala and F# curry natively too, via => chaining; Python has no automatic equivalent and reaches for functools.partial instead, or nested lambdas by hand; JavaScript sits in between, manual by default, with libraries filling the gap.

Remember: currying doesn't change what a function computes, only how many calls it takes to hand over the arguments.

Sign in to try this knowledge check.

Method chaining: return this, or the chain breaks

Chaining, str.trim().toLowerCase().replace(...), is not a language feature. It is a return-value convention: each method returns the same object, or one with a compatible interface, instead of undefined, and that return value is exactly what the next .method() call in line operates on.

JavaScript
class QueryBuilder {
  constructor() { this.parts = []; }
  where(cond)  { this.parts.push(`WHERE ${cond}`); return this; }
  orderBy(col) { this.parts.push(`ORDER BY ${col}`); return this; }
  build()      { return this.parts.join(" "); }
}

new QueryBuilder().where("age > 18").orderBy("name").build();
// "WHERE age > 18 ORDER BY name"

Walk it through: new QueryBuilder() starts with parts: []. .where(...) pushes onto parts and returns this, the same instance, giving the next call something to land on. .orderBy(...) does the same. .build() finally returns a plain string instead of this, which is fine, since it is the last call in the chain and nothing needs to call a method on its result. Miss a return this on any of the middle methods and the chain breaks exactly there: the next call in line tries to call a method on undefined and throws. That is the first thing worth checking whenever a chained call throws "cannot read properties of undefined." This is the Builder pattern's entire mechanism, and it is how jQuery, assertion libraries like expect(x).to.be.a("string"), and array methods like .filter().map() all work.

Remember: a chain is just a convention where every method returns something the next .method() call can land on. Forget return this and the chain breaks at exactly that call.

Sign in to try this knowledge check.
PreviousVariables, Scope, Hoisting, and TruthinessNextObjects and Prototypal Inheritance

Course progress

0%
0 of 177 modules complete

On this page

  • call, apply, bind: three ways to control this
  • The in operator: existence, not truthiness
  • Currying: one argument at a time
  • Method chaining: return this, or the chain breaks