Reputation: 5016
After reading this tutorial I think I have some grasp of how to use call and apply. However, I'm still left slightly confused.
Is there any situation in which using function.call(this, arguments)
would be different than using this.function(arguments)
?
If not, then why do we need the call
function?
Upvotes: 7
Views: 545
Reputation: 501
this.function(arguments)
is same as this.function.call(this, arguments)
. So when we should use call?
Question: suppose we have two objects Cycle and Mechanic
function Cycle(pressure) {
this.pressure = pressure;
this.decreasePressure = function() {
this.pressure -= 1
}
}
function Mechanic(mechanicWorking) {
this.mechanicWorking = mechanicWorking
}
Suppose if mechanic wants to decrease Cycle's pressure then how he should do it. ans:
Cycle cycle = new Cycle(24);
Mechanic mechanic = new Mechanic(true);
mechanic.decreasePressure = cycle.decreasePressure;
mechanic.decreasePressure() // will give error
but:
mechanic.decreasePressure.call(cycle) // will decrease pressure of cycle
Upvotes: 1
Reputation: 29010
There is no difference (other than that using .call
means that your code may take an unexpected path if someone overwrite the property call
of the function or Function.prototype.call
). However, you can write this.function()
only when the function actually exists as a property of this
!
Consider this example that shows how it can make sense to use call
:
const nodes = document.querySelectorAll('div')
// console.log(nodes.map(node => node.innerText)) would fail
// because nodes is of type NodeList which doesn't have a map
// method. But, it is array-like (has numeric indices and a length
// property) so we can use the original map method of the array
// prototype:
console.log(Array.prototype.map.call(nodes, node => node.innerText))
Or another example:
// This simulates an object we got from somewhere else
const something = {
val: 123,
calc (x) {
return this.val / x
}
}
// We want to monkey-patch the calc method so it doesn't return Infinity
// on x being zero (this may be necessary if we don't have access to the
// library that provided the something object, and forking it is not
// feasible)
const prevCalc = something.calc
something.calc = function (x) {
if (x === 0) {
return null
} else {
// Without using call, the invokation of the original method would
// not have the right this
return prevCalc.call(this, x)
}
}
Upvotes: 1
Reputation: 6526
const person = {
name: "Bob",
greet: function() { console.log("Hello " + this.name) }
};
const thank = function() {
console.log("Thanks " + this.name);
}
person.greet()
is the same as person.greet.call(person)
, but the first is more succinct, so this is why this variant exists.
call
function is useful when function is not member of the object. You can't call person.thank()
, you must call thank.call(person)
.
Upvotes: 2