Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript call to chain constructors for an object

Tags:

javascript

1) call

var obj = {num:2};

var add = function(a){
    return this.num + a;
};

add.call(obj, 1); //function.call(obj, arg)

2) call to chain constructors for an object.

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

var Food = function(name, price) {
    Product.call(this, name, price); // <-- 1. Product is obj constructor not fun
                                     //     2. what is 'this' here?
    this.category = 'food';
}

var cheese = new Food('feta', 5);

console.dir(cheese);

I'm currently study javascript oop, I found an example about Function.prototype.call() chain constructors, but I don't understand how it works.

1) isn't call required function call obj? but Product is construct.

var food = { category : 'food' };

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

var cheese = Product.call(food);
console.dir(cheese);//this will become undefine

2) what is 'this'? Food object? Product.call(new Food, name, price);?

*final result var cheese will be an object, Product.call(new Food obj, name, price)

Product still a function, why result become an object?

like image 438
Benjamin W Avatar asked Dec 27 '16 09:12

Benjamin W


People also ask

How do you call a constructor in JavaScript?

In JavaScript, a constructor gets called when an object is created using the new keyword.

How do you call a function inside an object in JavaScript?

The call() method is a predefined JavaScript method. It can be used to invoke (call) a method with an owner object as an argument (parameter). With call() , an object can use a method belonging to another object.

How can I have multiple constructors in JavaScript?

You simply add overloaded versions of the constructor function, much as you add overloaded versions to any method. But JavaScript doesn't enforce strict argument lists and doesn't have a concept of function overloading.

Can you call a method in a constructor JavaScript?

Yes, it is possible, when your constructor function executes, the this value has already the [[Prototype]] internal property pointing to the ValidateFields.


1 Answers

Both Product and Food are used as constructors, which means nothing more than that they are functions, and they can be called with new (but don't necessarily have to). The Food constructor makes use of Product to extend the object that is created with new Food(...).

It is vital to understand that when you call a function with new, a new, empty object is created that is available to that function as this. In the function you can then add properties to it. Also, if a function does not have a return statement in it, it still will return an object when it is called with new: it is the constructed object that is called this within the function.

Some magic happens with:

Product.call(this, name, price); // <-- 1. Product is construct not fun

Normally you would call Product like this:

new Product(name, price)

... but that creates and returns a new object. However, here the purpose is to extend the object created with new Food(...). That latter object is this. So instead of doing new Product(...) (which creates another new object), you pass the already existing object (this) to it. That you can do with .call(), which expects as the first argument the context -- the object that will be this during the Product function execution.

Note that in this case .call returns undefined, because the function is not called with new, and so the return value would be whatever the function returns explicitly. As there is no return statement in Product, it will return undefined. But that is of no interest here, as we only look to the side-effect the function call has on the first argument: this gets properties assigned to it.

So both the Product and the Food function get to add properties to the same object. When Food returns from the new Food() call, you'll have an object that is an instanceof Food.

Note that there are several ways to implement inheritance, and this way of doing it has some downsides, including:

  • the resulting object is not considered instanceof Product, and
  • properties which were defined on the Product.prototype will not be available to the object created with new Food().
like image 133
trincot Avatar answered Oct 12 '22 15:10

trincot