The Magic of this, call(), apply(), and bind() in JavaScript
What this means in JavaScript ?
this keyword refers to the context where piece of code is supposed to runs , functions or objects. this keyword represent global object . Global object (value of this) of browser is window and for node it is empty object.
this inside normal functions
Arrow function does not have reference of this keyword.
let obj = {
name : "ram",
callname(){
console.log(`${this.name} name called`);
},
calarrow: ()=>{
console.log(`${this.name} name called`);
}
};
obj.callname();
obj.calarrow();
// ram name called
// undefined name called
Note - Regular nested function does not inherit this but nested arrow function inherit this.
const actor = {
name : "Ram",
bow(){
return `${this.name} takes a bow`;
}
}
const detachedbow = actor.bow;
console.log(detachedbow());
// output = undefined takes a bow
console.log(typeof this); // object
const obj = {
crew : "spot girls",
prepareprops(){
console.log(`Outer this.crew : ${this.crew}`);
function arrangechairs(){
console.log(`Inner this.crew : ${this.crew}`);
}
arrangechairs();
const arrangelight = ()=>{
console.log(`Arrow this.crew : ${this.crew}`);
}
arrangelight();
},
}
obj.prepareprops();
// Output
// Outer this.crew : spot girls
// Inner this.crew : undefined
// Arrow this.crew : spot girls
Javascript has some its own methods like this , call , apply and bind.
Detached methods - When we assign object methods to some variable or pass it like a callback function by removing from their original context , then we called it as detached method.
const actor = {
name : "Ram",
bow(){
return `${this.name} takes a bow`;
}
}
const detachedbow = actor.bow;
console.log(detachedbow());
// output = undefined takes a bow
console.log(typeof this); // object
In detached method, it has not reference of this keyword.
What call() does
Immediately invokes the function and accepts argument individually in a comma-separated list.
function cookdish(ingredient, style){
return `\({this.name} prepare \){ingredient} in ${style} style!`
}
const sharmakitchen = {name : "sharma ji kitchen"}
const guptakitchen = {name : "gupta ji kitchen"}
console.log(cookdish.call(sharmakitchen , "Paneer and spices" , "mugli"));
// output - Sharma ji kitchen prepares Paneer and spices in mugli Style!
What apply() does-
Immediately invokes the function and accepts arguments as a single array like object. It runs the function setting this = context and using an array like object args as a list of arguments. The only syntax difference between call and apply is that call expects a list of arguments, while apply takes an array-like object with them.
There is only a
const guptaorder = ["chole kulche", "Punjabi dhabha"]
console.log(cookdish.apply(guptakitchen, guptaorder));
// output - Gupta ji kitchen prepares chole kulche in Punjabi dabha Style!
Delaying decorator -
function f(x) {
console.log(x);
}
function delay(f , ms){
return function(args){
setTimeout(()=>{
f.apply(this , args);
} , ms)
}
}
let f1000 = delay(f, 1000);
let f1500 = delay(f , 1500);
f1000("test");
f2000("test");
What bind() does
It returns a new function with the specified this value . Method func.bind(context, ...args) returns a “bound variant” of function func that fixes the context this and first arguments if given. The exotic bound function object returned by f.bind(...) remembers the context (and arguments if provided) only at creation time.
A function cannot be re-bound.
function reportdelivery(location, status){
return `\({this.name} at \){location}:${status}`;
}
const deliveryboy = { name : "Ranveer"};
console.log("call:", reportdelivery.call(deliveryboy, "Lyari", "Ordered"));
console.log("apply: " , reportdelivery.apply(deliveryboy , ["Mars", "Pick up"]));
console.log("Bind : " , reportdelivery.bind(deliveryboy , "Haridwar" , "What"));
// Output
// call: Ranveer at Lyari:Ordered
// apply: Ranveer at Mars:Pick up
// Bind : [Function: bound reportdelivery]
const bindreport = reportdelivery.bind(deliveryboy , "Haridwar" , "What");
console.log(bindreport());
// Ranveer at Haridwar:What
Difference between call, apply, and bind
