Pro Q
Pro Q

Reputation: 5016

Is there a difference between `this.function()` and `function.call(this)`?

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

Answers (3)

pramod singh
pramod singh

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

CherryDT
CherryDT

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

TeWu
TeWu

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

Related Questions