eirikrl
eirikrl

Reputation: 438

Javascript call and apply on constructor functions

I understand how call (and apply) method works in the following example.

var Bob = {
  name: "Bob",
  greet: function() {
   alert("Hi, I'm " + this.name);
  }
}

var Alice = {
 name: "Alice",
};

Bob.greet.call(Alice);   // Hi, I'm Alice

From what I understand, what's happening above is he greet method of Bob object is invoked with the scope of Alice.

Can someone explain what is happening behind the scenes in the below example, where the call method is used on a constructor function which allows inheritance?

function Product(name, price) {
  this.name = name;
  this.price = price;

}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

var chicken = new Food('chicken','40');
console.log(chicken);  //{ name= "chicken", price="40", category="food"}

I can't make the connection between the first and second example, where the first example the call method is invoked on a function that is doing something (alert), whereas in the second example, the call method is used on a constructor function that is initializing some properties.

Upvotes: 2

Views: 255

Answers (2)

Matt
Matt

Reputation: 75317

It's a way of "borrowing" the constructor function of Product to initialize your new Food.

When you call a function with new, you're setting this to be the new instance. You're then doing Product.call (i.e. calling the Product function and setting this inside the Product function to be your new Food instance (which is this inside Food)), and passing your name and price.

After Product.call(this, name, price); you should find that this.name and this.price have been set.

This doesn't allow inheritance, nor do you gain inheritance; it just executes the constructor function Product on your new Food instance.

To gain inheritance, you'd also have to set the prototype of Food to be a new Product instance;

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

Product.prototype.showPriceIn = function (currency) {
    alert(this.price + currency);
} 

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

Food.prototype = new Product;

var chicken = new Food('chicken','40');
chicken.showPriceIn("$");

http://jsfiddle.net/hPWMN/


N.B: Be careful saying that "Bob is invoked with the scope of Alice"; this isn't true. Bob doesn't inherit the scope of Alice, the value of this inside the greet function is merely altered to be Alice. Inheriting the scope would imply Bob gains access to private variables and the like, which he doesn't.

Upvotes: 1

nanobash
nanobash

Reputation: 5500

I'll try to explain with simple example, here it is

function Human(name,surname){
    this.name = name;
    this.surname = surname;
}

Human.prototype.method = function(){
    alert("Hi " + this.name + " " + this.surname);
};

var obj = new Human("Name","Surname");
obj.method();

In this case Human is constructor in which you are defining properties name and surname. prototype function makes extending with method function where I'm using this key. It refers to specified objects , which are defined from outside.

With var obj = new Human("Name","Surname"); you are initializing Human class and passing there values (name,surname). In this case you have one object named obj , but you can defined as many you like

Upvotes: 1

Related Questions