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)"