JavaScript inheritance: calling a super constructor or using a prototype?

Most recently, I read about using JavaScript calls in MDC.

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call

One link from the example below, I still do not understand.

Why do they use inheritance here

Prod_dept.prototype = new Product(); 

It's necessary? Because there is a super constructor call in

 Prod_dept() 

anyway like this

 Product.call 

is it just because of normal behavior? When is it better to use a super constructor call or use a prototype chain?

 function Product(name, value){ this.name = name; if(value >= 1000) this.value = 999; else this.value = value; } function Prod_dept(name, value, dept){ this.dept = dept; Product.call(this, name, value); } Prod_dept.prototype = new Product(); // since 5 is less than 1000, value is set cheese = new Prod_dept("feta", 5, "food"); // since 5000 is above 1000, value will be 999 car = new Prod_dept("honda", 5000, "auto"); 

Thank you for understanding what to do.

+72
javascript inheritance prototype-programming chaining call
Nov 11 '10 at 9:28
source share
3 answers

The answer to the real question is that you need to do both:

  • Installing the prototype in the parent instance initializes the prototype chain (inheritance), this is done only once (since the prototype object is shared).
  • A call to the parent constructor initializes the object itself, this is done with each instance (you can pass different parameters each time it is created).

Therefore, you should not call the parent constructor when setting up inheritance. Only when creating an instance of an object that inherits from another.

Chris Morgan's answer is almost complete, there is no small detail (constructor property). Let me suggest a method for setting up inheritance.

 function extend(base, sub) { // Avoid instantiating the base class just to setup inheritance // Also, do a recursive merge of two prototypes, so we don't overwrite // the existing prototype, but still maintain the inheritance chain // Thanks to @ccnokes var origProto = sub.prototype; sub.prototype = Object.create(base.prototype); for (var key in origProto) { sub.prototype[key] = origProto[key]; } // The constructor property was set wrong, let fix it Object.defineProperty(sub.prototype, 'constructor', { enumerable: false, value: sub }); } // Let try this function Animal(name) { this.name = name; } Animal.prototype = { sayMyName: function() { console.log(this.getWordsToSay() + " " + this.name); }, getWordsToSay: function() { // Abstract } } function Dog(name) { // Call the parent constructor Animal.call(this, name); } Dog.prototype = { getWordsToSay: function(){ return "Ruff Ruff"; } } // Setup the prototype chain the right way extend(Animal, Dog); // Here is where the Dog (and Animal) constructors are called var dog = new Dog("Lassie"); dog.sayMyName(); // Outputs Ruff Ruff Lassie console.log(dog instanceof Animal); // true console.log(dog.constructor); // Dog 

See my blog post for even more syntactic sugar when creating classes. http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

The technique is copied from Ext-JS and http://www.uselesspickles.com/class_library/ and comment https://stackoverflow.com/users/1397311/ccnokes

+101
Dec 08 2018-10-10
source share

The ideal way to do this is not to do Prod_dept.prototype = new Product(); because it calls the Product constructor. Therefore, the ideal way is to clone it, except for the constructor, something like this:

 function Product(...) { ... } var tmp = function(){}; tmp.prototype = Product.prototype; function Prod_dept(...) { Product.call(this, ...); } Prod_dept.prototype = new tmp(); Prod_dept.prototype.constructor = Prod_dept; 

Then the super constructor is called at build time, which is what you need, because then you can also pass parameters.

If you look at things like the Google Closure Library, you'll see how they do it.

+28
Nov 11 '10 at 9:32
source share

If you have done object-oriented programming in JavaScript, you will know that you can create a class as follows:

 Person = function(id, name, age){ this.id = id; this.name = name; this.age = age; alert('A new person has been accepted'); } 

So far, our class has only two properties, and we are going to give it some methods. A clean way to do this is to use its 'prototype' object. Starting with JavaScript 1.1, a prototype object has been introduced in JavaScript. This is a built-in object that simplifies the process of adding custom properties and methods to all instances of the object. Let's add 2 methods to our class using its 'prototype' object as follows:

 Person.prototype = { /** wake person up */ wake_up: function() { alert('I am awake'); }, /** retrieve person age */ get_age: function() { return this.age; } } 

Now we have defined our Person class. What if we want to define another class called "Manager" that inherits some properties from Person. It makes no sense to redefine all these properties again, when we define our Manager class, we can just set its inheritance from the Person class. JavaScript does not have built-in inheritance, but we can use the method to implement inheritance as follows:

Inheritance_Manager = {}; // Create an inheritance manager class (name optional)

Now let's give our inheritance class a method called extend, which takes baseClass and subClassas arguments. Within the extend method, we will create an inner class called the inheritance () {} function. The reason we use this inner class is to avoid confusion between the baseClass and subClass prototypes. Then we prototype our inheritance class for the baseClass prototype, as with the following code: inheritance.prototype = baseClass. prototype; Then we copy the inheritance prototype into the subClass prototype as follows: subClass.prototype = new inheritance (); The next is to specify the constructor for our subclass as follows: subClass.prototype.constructor = subClass; After prototyping our subclass is complete, we can specify the following two lines of code to set some base class pointers.

 subClass.baseConstructor = baseClass; subClass.superClass = baseClass.prototype; 

Here is the complete code for our extended function:

 Inheritance_Manager.extend = function(subClass, baseClass) { function inheritance() { } inheritance.prototype = baseClass.prototype; subClass.prototype = new inheritance(); subClass.prototype.constructor = subClass; subClass.baseConstructor = baseClass; subClass.superClass = baseClass.prototype; } 

Now that we have implemented our inheritance, we can start using it to extend our classes. In this case, we are going to extend the Person class with the Manager class as follows:

Define the Manager class

 Manager = function(id, name, age, salary) { Person.baseConstructor.call(this, id, name, age); this.salary = salary; alert('A manager has been registered.'); } 

we inherit the Person form

 Inheritance_Manager.extend(Manager, Person); 

If you notice, we just called the extension method of our class Inheritance_Manager and in this case passed the subClass dispatcher, and then the name baseClass. Please note that the order is very important here. If you change them, inheritance will not work as you planned, if at all. Also note that you will need to specify this inheritance before you can define our subclass. Now define our subclass:

We can add several methods as shown below. Our Manager class will always have the methods and properties defined in the Person class, because it inherits it.

 Manager.prototype.lead = function(){ alert('I am a good leader'); } 

Now, to test it, we will create two objects: one from the Person class and one from the inherited Manager class:

 var p = new Person(1, 'Joe Tester', 26); var pm = new Manager(1, 'Joe Tester', 26, '20.000'); 

Feel free to get the full code and more comments at: http://www.cyberminds.co.uk/blog/articles/how-to-implement-javascript-inheritance.aspx

+6
Dec 21 '11 at 21:20
source share



All Articles