bind, call and apply
Three methods of Function.prototype that set this explicitly:
call(thisArg, a, b)calls the function immediately, arguments are passed one by one.apply(thisArg, [a, b])calls the function immediately, arguments are passed as an array.bind(thisArg, a, b)does not call the function. It returns a new function withthisand the first arguments fixed.
Details
bindcan fix arguments as well asthis. This is partial application.- A bound function can't be rebound: a second
bindandcall/applydo not change itsthis. - Arrow functions ignore the
thisargument of all three methods. - In non-strict mode
nullandundefinedpassed asthisare replaced with the global object. - With spread syntax,
fn.apply(obj, args)andfn.call(obj, ...args)are interchangeable.
See this.
Example
function showThisAndArgs(...args) {
console.log(this, ...args);
}
showThisAndArgs.call({}, 'a', 'b'); // {} a b
showThisAndArgs.apply({}, ['a', 'b']); // {} a b
const bound = showThisAndArgs.bind({}, 'a', 'b');
bound('c'); // {} a b c
bound.call({ x: 1 }, 'c'); // {} a b c
Follow-up Questions
- Where is
bindused in practice? To keep the context of a method passed as a callback and to fix the first arguments of a function. - What does
binddo when the bound function is called withnew? The boundthisis ignored and a new object is created; the fixed arguments are kept. - Write your own
bind:
Answer
Function.prototype.myBind = function (thisArg, ...boundArgs) {
const fn = this;
return function bound(...args) {
// `new bound()` ignores the bound `this`, like the native `bind`
if (new.target) return new fn(...boundArgs, ...args);
return fn.apply(thisArg, [...boundArgs, ...args]);
};
};
Common Mistakes
- Mixing up
callandapply. A mnemonic:applyand "array" both start with "a". - "
bindcalls the function." It only returns a new one.
See Also
- Functional Programming — currying and composition.