Javascript: OOP mit Javascript

Lange war Javascript für mich eine Skriptsprache die nur nebenbei fast unbemerkt im Browser lief. Bei einem kleinen Canvas Projekt (cangaja), das man ja mit Javascript programmieren muss, habe ich mich erst tiefer mit Javascript beschäftigt.

Und ich musste feststellen das Javascript unterschätzt wird (JavaScript: The World’s Most Misunderstood Programming Language). Diese Programmiersprache IST objektorientiert, vielleicht nicht komplett im Sinne von Java oder anderen streng typisierten OOP Sprachen.

Javascript ist in manchen Dingen genau das Gegenteil, aber die Grundzüge von OOP sind enthalten und ich habe für mich entschieden dass ich gut damit leben kann ;-)

Im Internet gibt es sehr gute Quellen dazu (Superclassy Inheritance In JavascriptSimple JavaScript Inheritance, usw.), wenn man ein bisschen sucht wird man schon fündig.

Aber die Entwicklung bleibt auch hier nicht stehen, wer kurz einen Blick in Kapitel 9.8 Objektorientierung in ECMAScript5 von „JavaScript Das umfassende Referenzwerk“ geworfen hat, weiß was die Uhr geschlagen hat ;-)

So nun genug geschrieben, jetzt müssen Snippets her, für mein schlechtes Gedächtnis. Und am besten noch nicht im ECMAScript5 style, der ist mir nämlich noch ein wenig zu hoch.

Folgend sind nun drei kleine Beispiele die fast ähnlich sind, aber sehr gut veranschaulichen wie OOP mit Vererbung in JS realisiert werden kann.

function ClassA(val) {
	this.val = val
}
ClassA.prototype.getValA = function () {
	return this.val + ' bar';
}

ClassB.prototype = new ClassA()
ClassB.prototype.constructor = ClassB
function ClassB(val) {
	//call Superclass constructor
	ClassA.call(this, val)
}
ClassB.prototype.getValA = function () {
	//call Superclass method
	return ClassA.prototype.getValA.call(this)
}
ClassB.prototype.getValB = function () {
	//call Superclass method
	return this.val
}

x = new ClassB('foo')
x.getValA() //foo bar
x.getValB() //foo

Im zweiten Beispiel ist die Eigenschaft parent die auf den prototype der Elternklasse zeigt.

function ClassA(val) {
	this.val = val
}
ClassA.prototype.getValA = function () {
	return this.val + ' bar';
}

ClassB.prototype = new ClassA()
ClassB.prototype.constructor = ClassB
ClassB.prototype.parent = ClassA.prototype //own 'super' property

function ClassB(val) {
	//call Superclass constructor
	ClassA.call(this, val)
}
ClassB.prototype.getValA = function () {
	//call Superclass method
	return this.parent.getValA.call(this)
}
ClassB.prototype.getValB = function () {
	//call Superclass method
	return this.val
}

x = new ClassB('foo')
x.getValA() //foo bar
x.getValB() //foo

Wieder nur eine kleine Änderung, die Objekterzeugung über Object.create().

function ClassA(val) {
	this.val = val
}
ClassA.prototype.getValA = function () {
		return this.val + ' bar';
}

ClassB.prototype = Object.create(ClassA.prototype) //object creation the new style
ClassB.prototype.constructor = ClassB
ClassB.prototype.parent = ClassA.prototype //own 'super' property

function ClassB(val) {
	//call Superclass constructor
	ClassA.call(this, val)
}
ClassB.prototype.getValA = function () {
	//call Superclass method
	return this.parent.getValA.call(this)
}
ClassB.prototype.getValB = function () {
	//call Superclass method
	return this.val
}

x = new ClassB('foo')
x.getValA() //foo bar
x.getValB() //foo