开发者

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("H开发者_C百科i, 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!


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;
}; 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜