JavaScript Class à la bennybennet

Eines der schwierigsten Dinge, zumindest für mich, beim lernen von JavaScript, ist die Gewöhnung an funktionale Programmierung und die Implementierung von OO. Letzteres, weil JavaScript nicht die gängige Syntax aus andere C-Like-Block-Syntax-Sprachen benutzt, um “Objektbaupläne” aka Klassen zu beschreiben. In JavaScript gibt es keine Klassen. Um Objekte in JavaScript zu definieren, müssen wir also auf ein anderes Mittel zurückgreifen.

Eine Beispiel-Klasse in Java:

package de.bennybennet.examples;
public class Example extends Parent {
String exampleVarPP = "I'm only visible for every class in this package.";
private String exampleVarPriv = "I'm only visible for this class";
public Example() {
System.out.println("...entered the constructor");
}
public String getExampleVarPriv() {
System.out.println("...entered method of Example: Getter exampleVarPriv.");
return this.exampleVarPriv;
}
}
view raw Example.java hosted with ❤ by GitHub

JavaScript bietet für die Definition von Objekten sogenannte Prototypen. Ist man es gewohnt mit Klassen zu programmieren, dauert es häufig eine Weile, bis man prototypenbasierte Programmierung versteht. Der Sinn hinter Objekten und deren Vererbbarkeit ist die Wiederverwendung von Code. In Klassenbasierten sprachen geschieht dies, logisch, durch Klassen. Klassen können von anderen Klassen erben. Objekte entstehen durch Instanzierung von Klassen. In prototypbasierten Sprachen, werden Objekte durch das Klonen bereits bestehender Objekte erzeugt. Hierdurch kann auch eine Vererbung realisiert werden. Das Objekt “Child” wird aus einem Klon vom Objekt “Parent” erstellt und kann anschließend um Attribute und Methoden erweitert werden, die dann nur dem Objekt “Child” und Klons vom Objekt “Child” zur Verfügung stehen, nicht aber Objekt Parent oder weiteren Klons von diesem. Das Objekt Parent war der Prototyp für den Klon “Child”. Es werden keine Instanzen im Java-Sinne von Objektbauplänen (Klassen, Prototypen) in JavaScript erzeugt, weshalb das “new” in JavaScript sehr irreführend ist. Weiteres und näheres möchte ich gerne in einem anderen Post beschreiben.

Die folgende Notation, um klassenähnliche Definition von Objekten in JavaScript zu haben, ist hauptsächlich als akademisch anzusehen. Ich habe sie in meinen ersten Begegnungen mit JavaScript abseits von jQuery erstellt, hauptsächlich um JavaScript besser zu verstehen. Ist JS dein täglich Brot (oder besser: soll es das werden), empfehle ich stark, keine klassenähnlichen Konstrukte in JavaScript zu verwenden. Setzte dich intensiv mit prototypenbasierter Programmierung auseinander und verstehe, wie diese in JavaScript umgesetzt ist / funktioniert.

/* Simple JavaScript Inheritance
* First draft!
* @author Benny Bennet Jürgens (http://ben.nyben.net)
* CC-by-sa 3.0 - please provide my name and url
*/
;(function() {
"use strict";
this.BBClass = function(ctor, proto) {
ctor.prototype = proto || {};
ctor.prototype.constructor = ctor;
ctor.extends = function(parent) {
function ChildBB() {
parent.prototype.constructor.apply(this, arguments);
ctor.apply(this, arguments);
};
ChildBB.prototype = ( typeof Object.create !== 'function') ?
(function(parent) {
function F() {};
F.prototype = parent.prototype;
var prototype = new F();
prototype.constructor = ChildBB;
return prototype;
})(parent)
: Object.create(parent.prototype, { constructor: { value: ChildBB, enumerable: false }});
return ChildBB;
}
return ctor;
}
}).call(this);
var Person = BBClass(function(isDancing) {
console.log("person");
this.dancing = isDancing;
});
Person.prototype.dance = function() {
return this.dancing;
};
var Ninja = BBClass(function(isDancing) {
console.log("ninja");
}).extends(Person);
Ninja.prototype.swingSword = function() {
return true;
};
Ninja.prototype.arraytest = [1,2,3,4];
var p = new Person(true);
var n = new Ninja(false);
Person.prototype.test2 = function() { console.log("test2 bestanden"); };
console.log(n.arraytest);
console.log(p.dance());
console.log(n.dance());
console.log(n.swingSword())
p.test2();
n.test2();
console.log("inherit ok?")
console.log( p instanceof Object);
console.log( p instanceof Person);
console.log( p instanceof Person && p instanceof Object && n instanceof Ninja && n instanceof Person && n instanceof Object);
=> person
=> person
=> ninja
=> [1,2,3,4]
=> true
=> false
=> true
=> test2 bestanden
=> test2 bestanden
=> inherit ok?
=> true
=> true
=> true
view raw class.js hosted with ❤ by GitHub

Ich empfehle auch die Kommentare im Gist einmal durchzulesen. Dort habe ich meine Gedanken während der Entwicklung runtergeschrieben.

One thought on “JavaScript Class à la bennybennet

  1. Pingback: Was macht das “new” Keyword in JavaScript? | bennybennet

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>