2

I'm trying to understand the call and apply methods in javascript. But I didn't understand why I should use it.

var person = {
   fullName: function() {
      return this.firstName + " " + this.lastName;
 }
}

var person1 = {
 firstName:"John",
 lastName: "Doe"
}
var person2 = {
 firstName:"Mary",
 lastName: "Doe"
}
var x = person.fullName.call(person1);  

I can do this example without using call and apply.

var person = {
   fullName: function(firstName, lastName) {
     return firstName + " " + lastName;
 }
}
var person1 = {
  firstName:"John",
  lastName: "Doe"
}
var person2 = {
  firstName:"Mary",
  lastName: "Doe"
}
var x = person.fullName(person1.firstName, person1.lastName); 

Or I don't understand this example.

function Product(name) {
  this.name = name;
}

function Pizza(name) {
   Product.call(this,name);
}

const pizza = new Pizza("Margherita");

When I think of this example, I can do with the prototype. Why use call or apply? Thank you

4
  • @Rup is correct Commented Oct 17, 2019 at 16:01
  • Okay, I fixed it. Can you check it now? Commented Oct 17, 2019 at 16:06
  • Okay, I totally changed the sample. What I want to know is where should I actually use it? @Rup Commented Oct 17, 2019 at 16:20
  • You use .call so the this context of a method is called in another context outside of its original context. By the way, using prototype in the last example would also be a waste if you just want a new Product. Commented Oct 17, 2019 at 23:17

3 Answers 3

1

A good use case is when you want to 'borrow' a function with a different context. Take the example below, you can definitely use inheritance to give Cat the bark function but maybe you don't want that function to exist on every instance but only want to use it in certain situations.

function Dog(name) {
    this.name = name
    this.bark = function() {
        console.log('woof' + this.name)
    }
}
const dog = new Dog('spot')

dog.bark() // woofspot


function Cat(name) {
    this.name = name
}
const cat = new Cat('cat')

dog.bark.call(cat) // woofcat

Sign up to request clarification or add additional context in comments.

Comments

0
function Product(name) {
  this.name = name;
}

function Pizza(name) {
   Product.call(this,name);
}

const pizza = new Pizza("Margherita");

That's inheritance. Pizza is a product. In other languages, for example PHP, inheritance looks like this:

class Foo {

  public function __construct() {
    // Do stuff specific for Foo
  }

}

class Bar extends Foo {

  public function __construct()(
    parent::__construct();
    // Do stuff specific for Bar
  }

}

Here, we don't have extends and in order to make it work, you need to say that the this in the parent constructor is the child.

Using call, you can say what the this in the Product() function/constructor is. In this case, it is the Pizza object (the new created an object {}). Without using call, Pizza wouldn't even have a name.

The same goes for your first example

var person = {
   fullName: function() {
      return this.firstName + " " + this.lastName;
 }
}

var person1 = {
 firstName:"John",
 lastName: "Doe"
}
var person2 = {
 firstName:"Mary",
 lastName: "Doe"
}
var x = person.fullName.call(person1);  

Yes, it worked without calling call but not without drastic changes.

person.fullName.call(person1); is like saying take this function and permute this with my person1 object. So in the end, it is as though you did this:

return person1.firstName + " " + person1.lastName;

As to which one to use

Note: While the syntax of this function is almost identical to that of call(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.

10 Comments

Can't I do the same with inheritance? @jperl
@omerstack what do you mean? that's already inheritance. Pizza inherits from Product. In Pizza, we say call Product but use the context of Pizza (this). So this.name is like saying (Pizza).name = name; and then you can add properties to Pizza after the call to Product.
I mean, could I do it using Object.create and prototype? Because as I read, we use prototype for inheritance.
@omerstack please, see this developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/…. It also explains how to inherit the methods on the Product's prototype.
@omerstack the prototype is used for functions shared by instances of an object. But you need to do call to inherit the properties in the constructor.
|
0

As far as I know, it is all a matter of preference on which you use, but you must use call and/or apply, you cannot do it without them.

5 Comments

I don't understand why I can't. But if you say it's a matter of choice, I get it.
If you remove both, you should get what @Rup posted under comments.
Okay, I totally changed the sample. What I want to know is where should I actually use it? @Death Waltz
@omerstack look at the other answer, It does a better job of explaining than I did

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.