Lesson 54: Mastering JavaScript Function binding with challenges!

manoj ymkmanoj ymk
5 min read

πŸ”§ What Is Function Binding?

In JavaScript, functions are first-class objects and not automatically bound to their object. When you pass a method around (e.g. to setTimeout), its connection to its object can be lost β€” this becomes undefined (strict mode) or window (non-strict mode in browsers).

Function.prototype.bind lets you fix the value of this (and optionally some arguments) in advance, producing a new bound function.

πŸ“Œ Syntax

let boundFunc = originalFunc.bind(thisArg, arg1, arg2, ...);
  • thisArg: The value to permanently bind to this.

  • arg1, arg2, ...: Optional arguments for partial application.

βœ… Basic Example

let user = {
  name: "Alice",
  greet() {
    console.log(`Hello, ${this.name}`);
  }
};

setTimeout(user.greet, 1000);       // ❌ undefined, `this` is lost
setTimeout(user.greet.bind(user), 1000); // βœ… Hello, Alice

βœ… Partial Application Example

function multiply(a, b) {
  return a * b;
}

const double = multiply.bind(null, 2);
console.log(double(5)); // 10

πŸ”Ή 2. Fill Any Gaps β€” Edge Cases, Internals & Gotchas

🧠 How bind Actually Works Internally

  • bind() creates a new function object.

  • This function stores:

    • Reference to the original function.

    • Fixed this value.

    • Any partially applied arguments.

Calling the bound function will always invoke the original with the bound this and any bound arguments, followed by any new arguments.

πŸ”₯ Common Mistake #1: Method Extraction

let obj = {
  x: 42,
  getX() { return this.x; }
};

let getX = obj.getX;
console.log(getX()); // ❌ undefined

let bound = obj.getX.bind(obj);
console.log(bound()); // βœ… 42

⚠ Common Mistake #2: Rebinding Doesn’t Work

function f() {
  console.log(this.name);
}

let bound = f.bind({ name: "John" });
let reBound = bound.bind({ name: "Jane" });

reBound(); // πŸ”₯ Still John β€” bind only works once!

πŸ§ͺ Browser Quirks

  • In non-strict mode, this becomes the global object (window) if not set.

  • In strict mode, this remains undefined.

  • Node.js timers set this to the timer object; browser setTimeout sets it to window (or undefined in strict mode).

πŸ’‘ bind + arrow functions?

let obj = {
  name: "Test",
  arrow: () => console.log(this.name)
};

let boundArrow = obj.arrow.bind({ name: "Bound" });
boundArrow(); // ❌ undefined β€” arrow functions ignore bind!

Arrow functions lexically capture this and ignore .bind().


πŸ”Ή 3. Challenge Me Deeply (10 Problems)

🟒 Basic

  1. βœ… Create a bound function that logs the current user's name using .bind().

  2. βœ… Use a wrapper function to preserve this in a setTimeout.

🟑 Intermediate

  1. 🟑 Why doesn’t rebinding a .bind() result change this? Demonstrate with code.

  2. 🟑 Implement a custom partial() utility without using bind.

  3. 🟑 Create a utility bindAll(obj) that binds all function properties of obj to itself.

  4. 🟑 What happens if you use bind() with a class method and then subclass it? Demonstrate inheritance edge case.

πŸ”΄ Advanced

  1. πŸ”΄ Rewrite a recursive function (like factorial) to preserve this even when it's assigned to another variable.

  2. πŸ”΄ Write a polyfill for Function.prototype.bind.

  3. πŸ”΄ Compare and contrast .bind(), arrow functions, and closures for preserving this in a React component.

  4. πŸ”΄ Can you create a version of .bind() that also memoizes the function output based on arguments?

🎯 Bonus β€œaha!”:

  • Create a function that uses .bind() and setTimeout such that the result differs depending on whether you use .bind() or an arrow function. Explain why.

πŸ”Ή 4. Interview-Ready Questions

βœ… Conceptual

  • What problem does bind() solve?

  • How does bind() differ from arrow functions for managing this?

  • What happens if you pass a class method as a callback without binding it?

❓ Debugging Scenarios

  • You're using setTimeout(this.method, 1000) and it logs undefined. Why?

  • You used bind, but the method still logs the wrong value. What went wrong?

⚠ Red Flags / Best Practices

πŸ’‘ Best Practice⚠ Red Flag
Use .bind() in constructor for class methods (React pre-hooks)Relying on arrow functions for deep prototype methods
Use custom bindAll() to avoid boilerplatePassing unbound methods to callbacks
Prefer arrow functions in modern codebases for closuresAttempting to rebind a bound function

πŸ”Ή 5. Real-World Usage

βœ… In Production

  • React (Pre-hooks): Class components often bind methods in constructors:

      this.handleClick = this.handleClick.bind(this);
    
  • Event Listeners: Binding handlers to DOM elements or objects.

  • Partial Application: Libraries like Lodash's _.partial allow concise currying:

      const sendFromAlice = _.partial(send, "Alice");
    

βœ… Used in Libraries

  • _.bind, _.bindAll, and _.partial in Lodash.

  • Memoization with bound context in Redux middlewares.

  • In Vue 2's internal event binding logic.

  • Old AngularJS used bind for directive/controller context control.


πŸ”Ή 6. Remember Like a Pro

🎯 Mnemonic

β€œBind fixes this in place.”
Just like a seatbelt "binds" you to your seat β€” you’re not going anywhere.

🧭 Visual Cheatsheet

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Situation  β”‚ Solution                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ setTimeout β”‚ Use wrapper or .bind()               β”‚
β”‚ this lost  β”‚ Use arrow function or bind           β”‚
β”‚ Partial    β”‚ .bind(null, arg1, ...)               β”‚
β”‚ Arrow Fn   β”‚ Ignores bind(), uses lexical this    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”Ή 7. Apply It in a Fun Way

🎨 Mini Project: Bound Timer Utility

βœ… Build a small timer object that:

  • Starts counting seconds

  • Logs time every second using setInterval

  • Uses .bind() to ensure the correct context

βœ… Steps:

  1. Create a Timer object with start() and stop() methods.

  2. Use this.seconds to track time.

  3. Use setInterval with a bound logging function.

  4. Include a pause/resume feature that preserves this.

🧠 Sample Output

timer.start(); // 1, 2, 3 ...
timer.pause(); // stops
timer.resume(); // continues at 4 ...

βž• Bonus: Extend it

  • Add a UI with buttons.

  • Add lap recording.

  • Store state in localStorage (bind-safe!).


🧠 (Optional Deep Value)

πŸ”§ Open Source Examples

  • React: class components with .bind(this)

  • Lodash: _.bind, _.partial

πŸ›‘ Common Mistakes

  • Forgetting to bind in constructors (pre-hooks React).

  • Trying to rebind a bound function.

  • Using .bind() on arrow functions (has no effect).

πŸš€ Performance Tips

  • Avoid binding in render loops.

  • Prefer arrow functions if this doesn’t need rebinding.

  • Use bindAll() at construction time to avoid repeated binding.

0
Subscribe to my newsletter

Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

manoj ymk
manoj ymk