Compile Ready
Module 7 · The this Keyword

Function.prototype.bind

Intermediate10m read8m practice18m total
thisbindExplicit BindingPolyfills

Introduction

Function.prototype.bind does not invoke the function immediately. It returns a new function whose this is permanently set for normal calls, optionally with some arguments pre-filled.

Use bind when you need to pass a function around but keep its receiver, especially for callbacks.

Why This Matters

bind is the standard answer to the lost-method problem: setTimeout(user.save.bind(user), 1000). Interviewers also ask candidates to implement a simplified bind because it tests closures, this, apply, argument concatenation, and constructor edge cases.

Theory

Syntax

const bound = fn.bind(thisArg, presetArg1, presetArg2)

bind returns a new function. When that new function is called, it invokes the original function with:

  • this fixed to thisArg for normal calls.
  • preset arguments placed before later arguments.

Hard binding

A bound function ignores later attempts to change this with call or apply. Once bound, normal calls use the bound receiver.

Partial application

bind can pre-fill leading arguments. This is useful when you want a specialised function: const addTax = calculate.bind(invoice, 0.18).

bind vs call/apply

ToolInvokes now?Argument styleMain use
callYesSeparate argumentsImmediate explicit call
applyYesArray-like argumentsForward collected args
bindNoPreset plus later argsSave receiver for later

Constructor caveat

Native bind has a special rule with new: if a bound function is used as a constructor, the newly-created object becomes this, not the bound receiver. Many interview polyfills start with a simplified normal-call implementation, then discuss constructor support as a follow-up.

Arrow caveat

Binding an arrow returns a new callable function, but it does not change the arrow's lexical this.

Visual Diagrams

bind stores receiver and leading arguments
const bound = fn.bind(receiver, 'A')
                    |
                    +-- remembers receiver
                    +-- remembers leading argument 'A'

bound('B')
  |
  +-- invokes fn with:
      this === receiver
      arguments === ['A', 'B']

`bind` is delayed explicit binding plus optional partial application.

Code Examples

Fix a lost callback with bind

The bound function can be passed around safely because normal calls use the stored receiver.

Loading…

Partial application with bind

Preset arguments are placed before arguments supplied later.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function show(prefix, suffix) {
2 console.log(prefix + this.name + suffix);
3}
4
5const user = { name: 'Ada' };
6const bound = show.bind(user, 'Hi ');
7
8bound('!');
9bound.call({ name: 'Grace' }, '?');

Predict the output #2

javascript
1function add(a, b, c) {
2 console.log(this.base + a + b + c);
3}
4
5const addFromTen = add.bind({ base: 10 }, 1, 2);
6addFromTen(3);

Coding Exercises

Implement myBind with apply and concatenated args

Hard

Implement Function.prototype.myBind for normal function calls. It should return a new function, preserve the chosen thisArg, support preset arguments, and append later arguments. Use apply plus concatenated arrays. As a stretch follow-up, discuss how native bind behaves when the bound function is called with new.

Interview Questions

1What is the difference between `call`, `apply`, and `bind`?

call and apply invoke immediately with an explicit this; call takes separate arguments while apply takes an array-like argument list. bind does not invoke immediately. It returns a new function with fixed this for normal calls and optional preset arguments.

Asked at:GoogleAmazonMicrosoft
2How would you implement a simplified `bind`?

Store the original function from this, store preset arguments, and return a wrapper. When the wrapper is called, collect later arguments, concatenate preset and later arguments, then call originalFn.apply(thisArg, allArgs). Then mention the advanced follow-up: native bind has special behavior when used with new.

Follow-ups

  • How does native `bind` behave with `new`?
  • Can `bind` change an arrow function's `this`?

Quiz

1. What does `bind` return?

2. After `const bound = fn.bind(obj)`, what happens in `bound.call(other)` for a normal call?

Summary

  • `bind` returns a new function instead of invoking immediately.
  • The bound function stores a receiver for normal calls.
  • Bound functions can also store leading preset arguments.
  • Later `call` or `apply` cannot replace a bound function's receiver for normal calls.
  • A simplified `bind` polyfill uses a closure, argument concatenation, and `apply`.

Cheat Sheet

Syntax: const bound = fn.bind(thisArg, preset1).

Timing: later invocation.

Receiver: fixed for normal calls.

Arguments: preset arguments come before later arguments.

Polyfill idea: capture original function + receiver + preset args, return wrapper, call originalFn.apply(thisArg, presetArgs.concat(laterArgs)).

Caveats: native bind has special new behavior; arrows ignore bound this.