calling a function and call vs apply

  • mnemonic is “A for array and C for comma.”
  • call and apply are used when you want to bind different this object while calling function
  • Following is the signature:
functionName.call(object, param1, param2, ...); // comma separated params
functionName.apply(object, [param1, param2, ...]); // params in array
functionName.bind(object, param1, param2, ...); // comma separated params
functionName(param1, param2, ...); // directly invoking function
  • Here the object will become this when the function is invoked
function greet(lastName) {
    console.log(this.firstName + ' ' + lastName);
}
 
greet.call({ firstName: "John" }, "Doe"); // John Doe
greet.apply({ firstName: "Jane" }, ["Doe"]); // Jane Doe

bind

  • It binds the this object and return another function
  • It doesn’t modify the original function
function greet(lastName) {
    console.log(this.firstName + ' ' + lastName);
}
 
let bindedGreet = greet.bind({ firstName: 'John' }, "Doe");
 
bindedGreet(); // John Doe
 
//////////////////////////////////////////////////////////
 
var obj2 = {
  name: 'LL'
}
 
var testFun = (function() {
  console.log(this.name);
}).bind(obj2);
 
var obj = {
  name: 'KK',
  test: testFun
};
 
// testFun is pre-binded and hence does not print KK
obj.test(); // LL
  • Useful Example:
var clickHandler = {
	message: 'click event handler',
	handleClick: function(event) {
		console.log(this.message);
	}
};
 
var btn = document.getElementById('myBtn');
// Add click event to btn
btn.addEventListener('click', clickHandler.handleClick);
// Button click causes "undefined" to be printed
 
// Using bind to fix the code
btn.addEventListener('click', clickHandler.handleClick.bind(clickHandler));
// Button click causes "click event handler" to be printed
  • With Arguments
    • The extra parameters in bind prepends as arguments when we call the function
function log(...args) {
  console.log(this, ...args);
}
const boundLog = log.bind("this value", 1, 2); // prepend argument: 1, 2
const boundLog2 = boundLog.bind("new this value", 3, 4); // prepend: 3, 4
boundLog2(5, 6); // "this value", 1, 2, 3, 4, 5, 6

this

  • call, apply and bind helps us change the this reference while calling function
  • this is protected to be changed in global context
  • In global context:
    • In browser, this is same as window in global context
    • In Nodejs, this is an empty object and DOES NOT point to global in global context