Kategorien
Diplomarbeit

Vererbung in Javascript anhand von Exceptions

Hab noch zwei weitere Artikel gefunden, beide englisch:

Jop, ein weiterer Artikel zu Javascript. Und zur „komischen“ Vererbung von Javascript.

Jeder Programmierer kennt Exceptions, diese netten Fehler die einen an den Kopf geschmissen werden, wenn was schief läuft. Auch sowas gibts bei Javascript:

try {
  doSomething();
} catch(e) {
  alert(e.toString());
}

Klassisches try/catch-Statement. Demnächst muss ich nochmal nachschauen wie man „verschiedene“ Exceptions erkennt und dann getrennt behandelt. Nunja, weiter gehts, wir bauen uns eine Exception:

throw 42;
throw "I'm a string";
throw {toString: function() { return "I'm an object!"; } };

Alles wunderbar, aber String-Nachrichten schmeissen kann ja jeder. Kommen wir also zu der „BaseException“:

function BaseException(_message) {
	this.name = "BaseException";
	this.message = _message;
}
BaseException.prototype = {
	name : null,
	message : null,
	toString : function() {
		return this.name + ': "' + this.message + '"';
	}
}

Erstmal was ganz simples. Kann man z.B. so schmeissen und fangen:

try {
  throw new BaseException("foobar");
} catch (e) {
  alert(e.toString()); // alerts: "BaseException: foobar"
}

Schön, nicht wahr? Jetzt brauchen wir noch Vererbung:

// ripped from http://www.sitepoint.com/blogs/2006/01/17/javascript-inheritance/ 
function extend(descendant, parent) {
	var sConstructor = parent.toString();
	var aMatch = sConstructor.match(/\s*function (.*)\(/);
	if (aMatch != null) {
		descendant.prototype[aMatch[1]] = parent;
	}
	for (var m in parent.prototype) {
		descendant.prototype[m] = parent.prototype[m];
	}
};

Dies ist wohl leider notwendig. Diese „extend“-Function macht das irgendwie wohl cross-browser-kompatibel. Nunja, für Mozilla-only geht es auch anders. Nunja, „geerbt“ wird jetzt so:

function OtherException(_message) {
	// call "super" constructor
	this.BaseException(_message);
	this.name = "OtherException";
}
// OtherException inherits from BaseException
extend(OtherException, BaseException);

Voilà. Fertig ist das Butterbrot:

try {
  throw new BaseException("foobar");
} catch (e) {
  alert(e.toString()); // alerts: "BaseException: foobar"
}
try {
  throw new OtherException("foobar");
} catch (e) {
  alert(e.toString()); // alerts: "OtherException: foobar"
}
Kategorien
Diplomarbeit

public, private und „privileged“ in Javascript

Jetzt wirds hässlich. Natürlich gibts „public“ und „private“ auch in Javascript. Allerdings, wie immer, ein bisschen anders:
Public

function Constructor(value) {
    this.membername = value;
}
Constructor.prototype.membername = value;

myConst = new Constructor("foobar");
print myConst.membername; // prints 'foobar'

Private

function Constructor(value) {
    var self = this;
    this.membername1 = value; // public member
    var membername2 = value + "private"; // private member
    function membername() { // private method
        print self.member; //access to public member in private method
        print membername2; // access to private member in private method
    }
}

myConst = new Constructor("foobar");
print myConst.membername1; // prints 'foobar'
print myConst.membername2; // prints 'undefined'
myConst.membername(); //no such function

Wenn man jetzt aber z.B. mittels dem property „prototype“ auf private-members zugreifen will, dann wird man scheitern. „public“ hat keinen Zugriff auf „private“. Dazu muss man die „privileged“-Methoden verwenden.

Privileged

function Constructor(value) {
    this.membername = function membername() {
        print "hi";
    };
}

myConst = new Constructor("foobar");
myConst.membername(); // prints "hi"
Kategorien
Diplomarbeit Sonstiges

Javascript-Klassen und Objekte

Habe gerade noch das hier gefunden: Class-Based vs. Prototype-Based Languages

Ich hab zwar schon hier auf einen schönen Artikel verwiesen, aber jetzt nochmal das ganze aus meinem Munde.

Javascript is Objektorientiert. Schon immer. Glaub ich. 1995 das erstmal mit Netscape veröffentlicht, sind wir inzwischen bei Javascript 1.8 angekommen (seit 18. Dezember 2007). Javascript wird übrigens von Mozilla „gemanaged“. Und Javascript ist nicht Ecmascript. Vielmehr ist Javascript ein Dialekt von Ecmascript.

Soviel dazu. Javascript implementiert ECMAScript, genauer ECMA-262, edition 3. Innerhalb davon gibt es keine „Klassen“ im eigentlichen Sinne. Viel eher werden direkt Objekte geboren.

function meinObjekt () {
    this.zahl = 1;
}

Und schon haben wir ein Objekt/Klasse mit dem Namen „meinObjekt“. Und eine Eigenschaft „zahl“ hat es auch.

var objekt = new meinObjekt();
window.alert(objekt.zahl);

Und somit kriegen wir ein Fenster mit einer „1“ drinnen. Es gibt auch private und öffentliche Eigenschaften/Methoden, allerdings ist Javascript da etwas bockig:

function meinObjekt () {
     var self = this;
 
    /** @private */
    var foobar = "private";
    var privateMethod = function () {
        window.alert(foobar  + " " + self.barfoo);
    };
 
    /** @public */
    this.barfoo = "public";
    this.public_method = function () {
        window.alert(foobar + " " + this.barfoo);
        private_method();
    };
}

Wer sich wundert was das „self“ soll, das liegt an Javascript. Während der Zugriff von öffentlichen auf private Methoden prima klappt, ist der Zugriff von privaten auf öffentliche Methoden … anders :). Hierzu wird einfach „this“ in „self“ kopiert und dann kann wie „this“ verwendet werden. Jippie.

Ich verwende den Spass gerade so:

var logger = function() {
};
logger.prototype = {
	log : function(msg) {
		console.log(this.getNow() + msg);
	},
	getNow : function() {
		return new Date();
	}
};
var foobar = new logger();
logger.log("foobar"); // prints "foobar"

Man spricht hier von „prototyp-basierter“ Objektorientierung. Interessant wirds in dem „neuen“ Standard ECMA-262, edition 4. Dort gibt es dann tatsächlich auch Klassen:

class C {
	var val // a variable property
	var large = Infinity // a variable property
	const x = 3.14 // a constant property
	function f(n) { return n+val*2 } // a method property
}

Da ja Javascript schön dynamisch ist, gibt es auch dynamische Klassen:

dynamic class C {
}
c = new C
c.x = 37 // adds a property
delete c.x // removes it again

Weiter gehts mit Vererbung, jetzt mit Schlüsselwörtern wie „extends“:

class C {
	var val
	function f(n) { return n+1 }
}
class BetterC extends C {
	var large = 123456 // new value property
	override function f(n) { return n*3 } // overridden method property
}

Es gibt auch „final“ als Schlüsselwort, eine so bezeichnete Klasse kann dann keine Kinder kriegen. Und zu guter Letzt werden auch Interfaces eingeführt. Somit wird Ecmascript und somit auch Javascript an die „normale“ Objektorientierung herangeführt. Die komplette Spezifikation des „neuen“ ECMAScripts findet sich unter:

http://www.ecmascript.org/es4/spec/overview.pdf