TL;DR
var BaseClass = function (bar) {
this.foo = bar;
};
BaseClass.prototype.doSomething = function () {
console.log("from base class");
};
var DerivedClass = function () {
BaseClass.apply(this, arguments);
};
DerivedClass.prototype = Object.create(BaseClass.prototype);
DerivedClass.prototype.doSomething = function () {
BaseClass.prototype.doSomething.call(this);
console.log("from derived class");
};
var cls1 = new DerivedClass('I am cls1');
cls1.doSomething();
// -> from base class
// -> from derived class
console.log(cls1.foo);
// -> "I am cls1"
Update
I'm updating my answer thanks to @HMR's remarks (see his comment below, very useful):
- "You should not create a new instance of
BaseClass when setting prototype of DerivedClass, use Object.create (and polyfill it if needed)"
- "You also forget to initialize the
BaseClass and take ownership of it's instance variables by having BaseClass.apply(this,arguments)"
1/ Using Object.create
var BaseClass = function () {
this.foo = 'bar';
};
BaseClass.prototype.doSomething = function () {
console.log("base class");
};
var DerivedClass = function () {
};
DerivedClass.prototype = Object.create(BaseClass.prototype);
Notes:
Object.create "copies" the prototype of Base into Derived
- The public property
this.foo is not copied over to Derived (because it's not part of the prototype) - See below point 2/
More information about Object.create here.
2/ BaseClass.apply(this, arguments)
As stated above this.foo is not available into Derived instances. To make it available we need to apply the Base constructor into the Derived constructor..
So all the privileged properties of Base (this.foo,..) are applied to the new instances of Derived.
var DerivedClass = function () {
// Calls `Base` constructor with `Derived` context
BaseClass.apply(this, arguments);
};
DerivedClass.prototype = Object.create(BaseClass.prototype);
More details about javascript inheritance in popular HMR's answer.
I leave my original answer for comparison & educational purposes.
The problem with your technique (while it could work as expected) is that the doSomething method is copied over to every single instances of BaseClass (because it's declared as a simple public property).
To avoid this, and thus share the doSomething method accross all instances of BaseClass, you should add it to the prototype of BaseClass:
var BaseClass = function () {
};
BaseClass.prototype.doSomething = function () {
console.log("base class");
};
You cannot notice any difference in the end result but, this way, the doSomething method is "inherited", not copied.
Now knowing that, to achieve prototypal inheritance in Javascript:
// Derived Class 1
var DerivedClass1 = function () {
};
DerivedClass1.prototype = new BaseClass();
var cls1 = new DerivedClass1();
cls1.doSomething();
// -> "base class"
// Derived Class 2
var DerivedClass2 = function () {
};
DerivedClass2.prototype = new BaseClass();
DerivedClass2.prototype.doSomething = function () {
console.log("derived class (2)");
};
var cls2 = new DerivedClass1();
cls2.doSomething();
// -> "derived class (2)"
Bonus, if you want to call the parent method from the DerivedClass:
// Derived Class 3
var DerivedClass3 = function () {
};
DerivedClass3.prototype = new BaseClass();
DerivedClass3.prototype.doSomething = function () {
BaseClass.prototype.doSomething.call(this);
console.log("derived class (3)");
};
var cls3 = new DerivedClass1();
cls3.doSomething();
// -> "base class"
// -> "derived class (3)"