Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance in JS: this.base = Class(); this.base() or ...?

I am trying to "get" inheritance in JS. I just discovered a neat way to basically copy all properties from one object into another:

function Person(name){
  this.name="Mr or Miss: "+name;

  this.introduce = function(){
    console.log("Hi, I am "+this.name);
  }
}

function Employee(name,title){
  this.title=title;

  this.base=Person;
  this.base(name);  

}

e = new Employee('tony', 'manager')
e.introduce();

Note that I have a Person() class with a constructor, and its attribute "name" is generated by the constructor. The great thing about this is also that then employee has ALSO the name in the constructor -- and voila', it creates the Person object using the same parameter.

If I had done this with the "Prototype" way:

function Person(name){

  this.introduce = function(){
    console.log("Hi, I am "+this.name);
  }
}

function Employee(name, title){
  this.name = name; /*  ?!?!?!?!? I can't call the proper constructor here */
  this.title = title;
}
Employee.prototype= new Person(); /* ?!?!? NO NAME HERE..>? */
Employee.prototype.constructor = Employee;


e = new Employee('tony', 'manager')
e.introduce();

Err.... now what? I can't even complete this: this.name in Employee cannot be set using the proper Person constructor; the creation of a Person object happens only once in the inheritance.

So... what am I missing? Is the first example I gave "the" way to go in my case? And is there a way to have the same result with the second example?

Help!

like image 929
Merc Avatar asked Jul 05 '11 13:07

Merc


People also ask

What is inheritance in JS?

Inheritance enables you to define a class that takes all the functionality from a parent class and allows you to add more. Using class inheritance, a class can inherit all the methods and properties of another class. Inheritance is a useful feature that allows code reusability.

How we will apply inheritance to JS?

In JavaScript, inheritance is supported by using prototype object. Some people call it "Prototypal Inheriatance" and some people call it "Behaviour Delegation". Let's see how we can achieve inheritance like functionality in JavaScript using prototype object.

What is base class in JavaScript?

The class to be extended is called a base class or parent class. The class that extends the base class or parent class is called the derived class or child class. Call the super(arguments) in the child class's constructor to invoke the parent class's constructor.


1 Answers

This kind of prototype inheritance is often done this way:

function Parent() {}

function Child() {
    Parent.call(this); // call the constructor of the parent
}

var Constr = function() {};
Constr.prototype = Parent.prototype;

Child.prototype = new Constr();
Child.prototype.constructor = Child;

So the "trick" is to assign the Parent.prototype as prototype to an empty function and set a new instance of this function as prototype of Child.

This is done so that extending Child.prototype does not extend Parent.prototype.

You also have to call the parent's constructor in the child's constructor. I guess this is the part you struggled with. Every function has a call [docs] and apply [docs] method which let's you explicitly set the element this should refer to inside the function.

In your example, it would look like:

function Employee(name,title){
  this.title=title;

  Person.call(this, name);
}

without assigning the constructor to a property of the instance.

In your example, this.base(name) works, because through assigning the constructor to a property of the instance (and calling it this way), this inside the function refers to that instance.


There are several libraries implementing this pattern, e.g. Google Closure library:

goog.inherits = function(childCtor, parentCtor) {
  /** @constructor */
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  childCtor.superClass_ = parentCtor.prototype;
  childCtor.prototype = new tempCtor();
  childCtor.prototype.constructor = childCtor;
}; 
like image 187
Felix Kling Avatar answered Sep 24 '22 02:09

Felix Kling