Native inheritance in JavaScript
06 April 2011Inheritance without a framework leads to panic attack even those who are experienced JS coders. Especially if it's needed to not just add more methods but also modify existing ones (dont ask why, it's ruthless OOP). But it is so simple (trollface).
function A () {}
var a = new A()
Yeap, a class in JS is just a function.
var o = new function () {}
Any function could be a class even a anonymous lambda.
function A () {}
A.prototype =
{
method: function () {}
}
var a = new A()
a.method()
In strict OOP methods get added with prototypes. Yes those guys prototypes.
function A () {}
A.staticMethod = function () {}
A.staticMethod()
staticMethod
is not available in instances.
function A () {}
function B () {}
B.prototype = new A()
Yes, exactly prototype = new A()
, not just prototype = A()
.
function A () {}
A.prototype =
{
methodA: function () {}
}
function B () {}
B.prototype = new A()
var b = new B()
b.methodA()
Here we have in class B
a useful methodA()
from class A
.
function A () {}
A.prototype =
{
methodA: function () {}
}
function B () {}
B.prototype = new A()
B.prototype.methodB = function () {}
var b = new B()
b.methodA()
b.methodB()
Now instances of class B
has two handy methods one from A
and one from B
.
function A () {}
function B () {}
B.prototype = new A()
var methodsB =
{
methodB1: function () {},
methodB2: function () {},
methodB3: function () {}
}
Object.extend(B.prototype, methodsB)
var b = new B()
b.methodB1()
b.methodB2()
b.methodB3()
Object.extend(dst, src)
just copies properties from src
to dst
. If you doctor allows you may replace Object.extend()
with for in
loop ;)
function A () {}
A.prototype =
{
methodA: function () {}
}
function B () {}
B.prototype = new A()
B.prototype.methodA = function () { alert(42) }
var b = new B()
b.methodA()
Alert window shows here.
function A ()
{
this.array = []
}
function B ()
{
A.apply(this)
}
B.prototype = new A()
var b1 = new B()
var b2 = new B()
console.log(b1.array == b2.array)
//>>> false
If A.apply(this)
would not get called, then all instances of B
share the same array
.
function A () {}
A.prototype =
{
methodA: function () {}
}
function B () {}
B.prototype = new A()
B.prototype.superMethodA = B.prototype.methodA
B.prototype.methodA = function ()
{
this.superMethodA()
}
var b = new B()
b.methodA()
Perfectly fine for simple cases.
function A () {}
A.prototype =
{
methodA: function () {}
}
function B () {}
B.prototype = new A()
B.prototype.methodA = function ()
{
A.prototype.methodA.apply(this)
}
function C () {}
C.prototype = new B()
C.prototype.methodA = function ()
{
B.prototype.methodA.apply(this)
}
var c = new C()
c.methodA()
Just always works.
function A () {}
A.prototype =
{
methodA: function () {}
}
function B () {}
B.prototype = new A()
var superMethodA = A.prototype.methodA
B.prototype.methodA = function ()
{
superMethodA.apply(this)
}
var b = new B()
b.methodA()
Performs better, but breaks if A.prototype
gets changed.
function A () {}
A.prototype =
{
setPosition: function (x)
{
this.x = x
}
}
function B () {}
B.prototype = new A()
B.prototype.setPosition = function (x, y)
{
A.prototype.setPosition.call(this, x)
this.y = y
}
function C () {}
C.prototype = new B()
C.prototype.setPosition = function (x, y, z)
{
B.prototype.setPosition.call(this, x, y)
this.z = z
}
var c = new C()
c.setPosition(1, 2, 3)
In result of a hidden sequential call of A#setPosition()
and B#setPosition()
inside C#setPosition()
, we get and object with data {x: 1, y: 2, z: 3}
.