Function.prototype.bind
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:
thisfixed tothisArgfor 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
| Tool | Invokes now? | Argument style | Main use |
|---|---|---|---|
call | Yes | Separate arguments | Immediate explicit call |
apply | Yes | Array-like arguments | Forward collected args |
bind | No | Preset plus later args | Save 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
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.
Partial application with bind
Preset arguments are placed before arguments supplied later.
Playground
Press Run to execute the code and see output here.
Output Prediction
Predict the output #1
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
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
HardImplement 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.
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.