Function.prototype.bind()
Creates a new function with this permanently fixed and any leading arguments pre-filled.
bind(thisArg)
bind(thisArg, arg1)
bind(thisArg, arg1, arg2)
bind(thisArg, arg1, arg2, /* …, */ argN)- Added in JavaScript ECMAScript 5 (2009)
Parameters
| Parameter | Type | Description |
|---|---|---|
$thisArg | any | The value to be passed as the this parameter to the target function when the bound function is called. If the function is not in strict mode, null and undefined are replaced with the global object, and primitive values are converted to objects. The value is ignored if the bound function is constructed using new. |
$arg1, …, argNoptional | any | Arguments to prepend to the arguments provided to the bound function when invoking the target function. |
Return value
FunctionA copy of the given function with the specified this value, and initial arguments (if provided).
Errors
Throws a TypeError if the value it is called on is not callable.
Changelog
- PHP ECMAScript 2015The bound function's name is specified as the target's name with a "bound " prefix, and its length is the target's length minus the number of pre-filled arguments, floored at 0.
- PHP ECMAScript 2015Bound functions do not have their own prototype property, but remain constructable when the target is; the thisArg is discarded under new.
bind() does not call anything. It returns a new function that, however it is later invoked, runs the original with the this you fixed and any arguments you pre-filled prepended to whatever the caller passes.
When to reach for it
- Handing a method to something that will call it plainly — a callback, a timer, an event listener. Detached methods lose their receiver; a bound copy keeps it.
- Partial application.
log.bind(null, "WARN")gives you awarn()that needs only the message. - Building a reusable extracted method, such as
const has = Object.prototype.hasOwnProperty.bind(obj).
What trips people up
Binding is permanent and one-shot. Re-binding an already-bound function does nothing — the inner binding wins, and call() and apply() on a bound function cannot override this either.
Every call returns a fresh function object. fn.bind(o) !== fn.bind(o), so binding inline inside a listener registration means you can never remove that listener. Bind once and store the result.
The returned function reports a name of "bound " + original.name and a reduced length, and it has no own prototype property, though new on it still works when the target is a constructor.
Example
When to use it
- Pass a class method as a callback without it losing its instance
- Pre-fill a logger's level so callers only supply the message
- Extract a built-in prototype method into a standalone helper
- Freeze a partially applied constructor, such as a Point with x pinned to 0
Frequently asked questions
What is the difference between bind() and call()?
bind() returns a new function for later use, while call() invokes the function immediately. Use bind() when you are handing the function to someone else — a callback, a timer, an event listener — and call() when you want the result right now.
Why doesn't bind() work a second time?
Because the first bind() produces an exotic bound function whose receiver is baked in; a second bind(), and call() or apply() on it, cannot change it. If you need a different this, bind the original target function again rather than the bound copy.
Should I use bind() or a class field arrow function?
A class field arrow (handle = () => {...}) is the common modern choice for auto-bound handlers, since it is created per instance with lexical this and needs no constructor wiring. bind() is still the right tool for partial application and for binding a function you did not write.
More examples
Binding happens once and cannot be undone
Re-binding is a no-op: second() still reports "first", and call() cannot override the bound receiver either. The last line prints false, which is why an inline .bind() inside addEventListener leaves you with a listener you cannot remove.
function who() {
return this.id;
}
const first = who.bind({ id: "first" });
const second = first.bind({ id: "second" });
console.log(first(), second());
console.log(first.call({ id: "ignored" }));
// Each bind() allocates a distinct function object
const target = { id: "x" };
console.log(who.bind(target) === who.bind(target));Bound functions under new
Under new the bound thisArg (null) is discarded and a fresh object is constructed, but the pre-filled 0 still applies, so p is {x: 0, y: 5} and instanceof Point holds. YAxis has no own prototype property yet remains constructable, and its length dropped from 2 to 1.
function Point(x, y) {
this.x = x;
this.y = y;
}
const YAxis = Point.bind(null, 0); // x is always 0
const p = new YAxis(5);
console.log(p.x, p.y);
console.log(p instanceof Point);
// The bound function has no own prototype property
console.log(Object.hasOwn(YAxis, "prototype"));
console.log(YAxis.name, YAxis.length);
Discussion