All topics
Functionsintermediate

Function.prototype.call, apply, and bind

Three methods for explicitly controlling what this refers to inside a function, with different argument-passing conventions.

Every JavaScript function has access to call, apply, and bind, three methods inherited from Function.prototype that let you explicitly control the value of this when the function executes, overriding whatever this would normally be based on how the function was called. This is a heavily tested interview topic because it's the classic solution to this-binding problems that predates arrow functions.

call/apply are like temporarily lending someone your ID for one specific transaction; bind is like getting them a permanent duplicate ID card that always identifies them as you, no matter which counter they use it at later.

Key Concepts

1
call(thisArg, arg1, arg2, ...) invokes the function immediately with this set to thisArg, passing the remaining arguments individually, one by one. apply(thisArg, argsArray) does exactly the same thing but takes the arguments as a single array instead of individually — useful when you already have an array of arguments and don't want to spread them manually (though the spread operator has made this distinction less important today, since fn.call(thisArg, ...argsArray) achieves the same result). Both call and apply execute the function right away and return its result.
call(thisArg, arg1, arg2, ...)thisthisArgapply(thisArg, argsArray)fn.call(thisArg, ...argsArray)
2
bind(thisArg, arg1, arg2, ...) is different: instead of calling the function immediately, it returns a brand-new function with this permanently locked to thisArg (any later attempt to override it, even with another call, is ignored), and optionally with some leading arguments pre-filled — this is exactly the partial application behavior mentioned in currying. The bound function can be called later, passed around, or used as an event handler, and it will always execute with the bound this no matter how it's eventually invoked.
bind(thisArg, arg1, arg2, ...)thisthisArgcall
3
A classic real-world use case is fixing the notorious 'losing this' problem when passing a class method as a callback (element.addEventListener('click', this.handleClick.bind(this))), since passing a method reference alone strips its connection to the instance. Arrow functions solve the same problem more concisely for many cases by lexically inheriting this, but call/apply/bind remain essential for borrowing methods from one object to use on another, and for meta-programming utilities.
element.addEventListener('click', this.handleClick.bind(this))thiscallapplybind