call(), apply() and bind()¶
call()¶
- The
call()method allows a property belonging to one object, to be used inside another object. call()sets thethiskeyword of the function, to the provided value.- With
call(), you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.
Syntax¶
call()
call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, arg2)
call(thisArg, arg1, ... , argN)
Examples¶
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
console.log(new Food('cheese', 5).name);
// output: "cheese"
const obj = {
num: 2,
};
function addToThis(a) {
return this.num + a;
}
console.log(addToThis.call(obj, 3));
// output: 5
// since the first arg, `this` keyword is not passed to the call method, `this` get's bound to the global object
const sData = 'Wisen';
function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // sData value is Wisen
apply()¶
- The
apply()method is very similar tocall(), except for the style in which the arguments are passed to the function. - In
apply(), instead of passing each of the arguments separately, you pass them as an array.
Example¶
const obj = {
num: 2,
};
function addToThis(a, b, c) {
console.log(this.num + a + b + c);
}
const a = 1,
b = 2,
c = 3;
addToThis.call(obj, a, b, c); // 8
addToThis.apply(obj, [a, b, c]); // 8
bind()¶
- The
bind()method creates a new bound function that wraps the function, on which it is called. - The bound function's
thiskeyword is set the provided value. - Calling the bound function results in the execution of its wrapped function.
Example¶
var obj = {
num: 2,
};
function addToThis(a, b, c) {
console.log(this.num + a + b + c);
}
var a = 1,
b = 2,
c = 3;
var arr = [a, b, c];
addToThis.call(obj, a, b, c); // 8
addToThis.apply(obj, arr); // 8
const bound = addToThis.bind(obj);
bound(a, b, c); // 8
Function currying with bind()¶
Function currying: Creating a copy of a function with some preset parameters. Useful in mathematical situations.
function multiply(a, b) {
return a * b;
}
var multiplyByTwo = multiply.bind(this, 2); // permanently sets the value of first parameter 'a'
multiplyByTwo(4); // 8
var test = multiply.bind(this, 2, 4); // both arguments of multiply() are permanently set
test(3); // 8 ('3' is passed as third argument)
Conclusion: More or less, all three methods help us inherit members of one object's in another object.
Few use cases,
let argsToArr = function () {
console.log([].slice.call(arguments)); // [1, 2, 3]
};
argsToArr(1, 2, 3);
let numArr = [2, 7, -1];
console.log(Math.min.apply(null, numArr)); // -1
let obj = {
asyncFunc(cb) {
cb();
},
parse() {
console.log('parser called');
},
render() {
that = this;
this.asyncFunc(function () {
that.parse();
});
},
};
obj.render();
Instead of the above workaround, you can bind outer this to the inner this of the callback.
render() {
this.asyncFunc(
function () {
this.parse();
}.bind(this)
);
};
If you don't bind the outer this, this.parse() will through an error, since there is no method called parse in the callback's scope.
The
argumentskeyword is a local variable available within all non-arrow functions. It is an Array-like object accessible inside functions that contains the values of the arguments passed to that function, with the first arg available at index 0.