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;
};
精彩评论