call/apply/bind in Javascript
Definition
func.call(thisArg, arg1, arg2, ...) func.apply(thisArg, [argsArray]) func.bind(thisArg[, arg1[, arg2[, ...]]])
These three functions allow you to attach a function to an object to make it act like a method, where “this” represents the object.
call and apply are identical, except call accepts a dynamic number of parameters, while apply accepts an array of values.
Sample Code
const Line = function() { this._spaces = []; for (let i = 0; i < 10; ++i) { this._spaces[i] = "."; } this.turnOn = function(idx) { this._spaces[idx] = "X"; }; this.turnOff = function(idx) { this._spaces[idx] = "."; }; this.toString = function() { return this._spaces.join(""); } }; const line = new Line(); const turnOnTwo = function (idx1, idx2) { this.turnOn(idx1); this.turnOn(idx2); }; console.log(line.toString()); // ..........
call
// "c"all = "c"omma separated parameters turnOnTwo.call(line, 3, 5); console.log(line.toString()); // ...X.X....
apply
// "a"pply = "a"rray of items turnOnTwo.apply(line, [0, 8]); console.log(line.toString()); // X..X.X..X.
bind
const boundFunction = turnOnTwo.bind(line); boundFunction(1, 2); console.log(line.toString()); // XXXX.X..X.
Reference
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Browser requirements
call and apply are available anywhere. bind requires IE9+ or a real browser.Polyfill
if (!Function.prototype.bind) { Function.prototype.bind = function(oThis) { if (typeof this !== 'function') { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function() {}, fBound = function() { return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); }; if (this.prototype) { // Function.prototype doesn't have a prototype property fNOP.prototype = this.prototype; } fBound.prototype = new fNOP(); return fBound; }; }