• Objektorientiertes JavaScript

    von am 2. August 2010

    Der erste Artikel dieser Art soll sich mit der objektorientierten Verwendung von Javascript beschäftigen – und ist für alle jene bestimmt die Javascript nur als nette kleine Ergänzung kennen, um z.B. beim Klick auf einen Button eine Fehlermeldung auszugeben.

    In meinem ersten Artikel für “phphatesme.com” soll es um die objektorientierten Ansätze von Javascript gehen. Der Artikel erhebt keinen Anspruch darauf, ein vollständigerer Guide für die objektorientierte Entwicklung mit Javascript in Webentwicklungen zu sein. Viel eher will ich euch zeigen, zu was Javascript alles fähig ist – und wo die Vorteile dieser Art von Entwicklung liegen.

    Anfangen möchte ich gerne mit einem praktischen Beispiel. In PHP:

    class MyWindow
    {
    	private $title = '';
    	private $size = null;
    
    	public function __construct($newTitle)
    	{
    		$this->title = $newTitle;
    	}
    
    	public function setSize($width, $height)
    	{
    		$this->size = array('width' => $width, 'height' => $height);
    	}
    }

    Klassen in Javascript funktionieren so leider nicht. Javascript kennt weder die Keywords “public” noch “private” noch einen Konstruktor. Bevor ich euch jetzt weiter auf die Folter spanne, hier die gleiche Klasse – in Javascript:

    function MyWindow(newTitle)
    {
    	var title = '';
    	var size = null;
    
    	this.setSize = function(width, height)
    		{
    			size = {width: width, height: height};
    		}
    
    	title = newTitle;
    }

    Und schon habt ihr es geschafft. Dem aufmerksamen Leser ist mit Sicherheit nicht entgangen, dass das erste Schlüsselwort des Codeschnippels “function” ist. Und hier kommen wir schon zum Knackpunkt der Objektorientierung in Javascript: Es wird nicht zwischen Objekten und Funktionen unterschieden.

    Der mit Abstand größte Vorteil der objektorientierten Javascript-Programmierung ist die bessere Speicherkontrolle. Gerade bei modularen Websites kann es aufgrund von Caches notwendig sein, dass alle Skriptdateien im Vorfeld geladen werden. Muss der Browser nun alle Funktionen im globalen Sichtbarkeitsbereich erstellen, braucht das neben Speicher auch CPU-Zeit. Erstellt man jedoch Objekte, z.B. auch einfach nur “Controller”-Objekte, werden die Methoden erst bei der Instanziierung des Objekts “angelegt”. Um das allgemeiner zu formulieren: Der Code innerhalb des äußeren “function”-Schlüsselworts wird erst beim Aufruf dieser Funktion ausgeführt.

    Um den Begriff “Controller” in diesem Zusammenhang etwas genauer zu erklären, möchte ich euch einfach ein kleines Skript vorstellen, welches z.B. dazu dienen könnte, einen “Artikel weiterempfehlen”-Layer einzublenden:

    function articleAdviseController(divId)
    {
    	var divElement = null;
    
    	this.show = function()
    		{
    			divElement.style.display = 'block';
    		}
    
    	this.hide = function()
    		{
    			divElement.style.display = 'none';
    		}
    
    	divElement = document.getElementById(divId);
    }

    Um das obige Beispiel zu vervollständigen hier noch der Beispielaufruf (vielen Dank für den Kommentar von Bastian):

    // Instanzierung, z.B. im HEAD-Bereich der Seite
    var myArticleController = new articleAdviseController('my_div_id');
    
    // Spätere Nutzung, z.B. im ONCLICK-Attribut eines Elements
    <a onclick="myArticleController.show()">Kommentare zeigen</a>
    <a onclick="myArticleController.hide()">Kommentare verstecken</a>
    

    Zu guter Letzt noch ein kleiner Ausblick auf den nächsten Artikel, in dem ich speziell auf das Thema “Sichtbarkeit” von Eigenschaften und Methoden eingehen möchte.

    22 Kommentare »


    • Ralph Meier
      am 2. August 2010 um 07:59 Uhr

      Danke für den Artikel. Hat mich schon lange gewundert, dass das Thema Javascript hier noch nicht aufgegriffen wurde, obwohls so wichtig ist.

      Ich beschäftige mich auch seit einigen Wochen intensiver mit Javascript und auf meinem Blog werden voraussichtlich einige Artikel über dieses Thema erscheinen.

      Folgender Artikel ist bei mir gerade heute erschienen :-)
      http://daraff.ch/2010/08/javascript-lernen-javascript-java/

      Ausserdem gibt es folgende übers testen und mocken mit javascript:
      http://daraff.ch/2010/07/javascript-mocking-mit-jsmockito-teil-i/
      http://daraff.ch/2010/07/javascript-unit-testing-mit-jstestdriver/

      Dann noch eine Frage an die Community, bei welcher ich mich in Javascript noch schwer tue.
      1. Wo gibt es gute Beispiele für TDD Entwicklung mit Javascript?
      2. Da javascript in einer Anwendung teilweise sehr mit HTML verknüpft ist: Welche Teile einer Javascript Applikation/Webseite soll ich mit unit tests abdecken und wie? Beispiele? Kann man GUI’s sinnvoll mit unit tests testen oder sollte man eher sowas wie Selenium verwenden? Wo ist die Grenze?

      Würde mich sehr über eine Antwort und über gute Quellen freuen.


    • Bastian
      am 2. August 2010 um 08:27 Uhr

      Interessanter Artikel. Ein paar Verbesserungsvorschläge: Beim letzten Script fehlt ein Beispielaufruf und dein “Ausblick” auch den nächsten Artikel ist etwas merkwürdig :-) Sonst ist der Artikel gut.


    • Stephan Schulze
      am 2. August 2010 um 08:37 Uhr

      Hallo Bastian,

      vielen Dank für deine konstruktive Kritik. Ein Beispielaufruf hätte an dieser Stelle wirklich nicht geschadet. Da will ich mal eben sehen, was da zu machen ist ;)

      Edit: Entsprechende Code-Beispiele wurden hinzufügt.

      Viele Grüße,
      Stephan


    • Christian Kaps
      am 2. August 2010 um 08:59 Uhr

      Mir fehlt im Artikel der Hinweis das es es nicht nur diese eine Art gibt in JavaScript objektorientiert zu programmieren(Stichwort prototyping). Weiterhin erwähnst du das es zwar keine Keywords für public oder private gibt, es aber doch möglich ist Member-Variablen als public oder private zu deklarieren. Das JavaScript keine Konstruktor kennt stimmt auch nicht. In deinem Beispiel ist der Konstruktor halt gleichzusetzen mit der Klassendefinition. Noch eine andere Frage. Wieso weist du einer Variable nicht gleich bei der Deklaration den Wert zu? Ich weiß das ist Geschmackssache, finde aber es erhöht die Lesbarkeit um ein vielfaches wenn man alles in eine Zeile schreibt.


    • Stephan Schulze
      am 2. August 2010 um 09:04 Uhr

      Hallo Christian,

      ja, ich kenne die Methode des “prototypings” auch. Jedoch ist dies mMn für ein “Einsteiger”-Thema ein Stück zu weit gegriffen, da es sich doch teilweise recht deutlich von PHP-Entwicklung abhebt.

      “private” und “public”-Schlüsselwörter gibt es nicht, dass es dennoch geht, sollte an den Code-Beispielen deutlich werden. Auf das Thema “Sichtbarkeit” soll es im nächsten Artikel gehen.

      Die Variablen-Zuweisung bei Initialisierung nutze ich in der Entwicklung meistens, da es die Lesbarkeit erhöht. In dem Beispiel zielte ich auf Parallelen zwischen der PHP-Funktion “__construct()” und dem Javascript-Code, um, wie oben bereits beschrieben, den Einstieg etwas leichter zu gestalten.

      Viele Grüße,
      Stephan


    • molily
      am 2. August 2010 um 09:08 Uhr

      Wer etwas tiefer einsteigen will, dem empfehle ich meine JavaScript-Dokumentation, darin die Texte zur Organisation von JavaScripten (http://molily.de/weblog/javascript-organisation), speziell den Abschnitt zu Konstruktoren, Prototypen und Instanzen:
      http://molily.de/js/organisation-instanzen.html


    • Wolfgang
      am 2. August 2010 um 09:13 Uhr

      Ist das nicht ein ziemlicher Overhead bei jedem new die Methoden neu zu deklarieren? Oder findet das der Interpreter heraus und optimiert es?

      Wolfgang


    • Markus Möller
      am 2. August 2010 um 09:25 Uhr

      Super! Mehr solche JavaScript-Artikel bitte.


    • Stephan Schulze
      am 2. August 2010 um 09:28 Uhr

      Hallo Wolfgang, hallo Markus,

      vielen Dank für eure Kommentare:

      @Wolfgang:
      Der Interpreter baut, so sieht es zumindest in Performance Messungen aus, das “Gerüst” genau einmal beim “new” Aufruf und hält es dann im Speicher, so dass ein zweiter “new” Aufruf deutlich schneller ist.

      @Markus:
      Schon in Arbeit ;)

      Viele Grüße,
      Stephan


    • Eric
      am 2. August 2010 um 09:33 Uhr

      Sehr schoener Artikel fuer Einsteiger, aber er vermittelt mir zu sehr den Eindruck, dass Javascript nichts weiter ist als eine weitere prozedurale Programmiersprache, was schlichtweg nicht der Fall ist.

      Fuer alle, die nicht lange genug auf die naechsten Artikel warten koennen sind durchaus die zwar mittlerweile leicht angestaubten, aber dadurch nicht schlechteren Artikel von Douglas Crockford zu empfehlen http://www.crockford.com/


    • Sebastian
      am 2. August 2010 um 10:36 Uhr

      Hallo,

      zum einen erst mal ein Lob ans gewählte Thema, genau das was ich brauche, ich bin genau die Zielgruppe ;-)

      Freue mich schon auf die nächsten Artikel.

      Was das Thema Konstruktor angeht, ich glaube Stephan ging es eher darum zu sagen, dass es hier eben nicht einen Konstruktor in Form einer Methode wie __construct() in PHP oder __init__(self) in Python (oder … in …) gibt.

      Gruß Sebastian


    • Christian Kaps
      am 2. August 2010 um 10:59 Uhr

      @Sebastian

      Das kann man so nicht sagen da es eine Konstruktor-Methode in JavaScript gibt.

      /**
      * Constructor
      */
      function Car(maxSpeed) {

      this.speed = 0;
      this.maxSpeed = maxSpeed;
      }

      Car.prototype.accelerate() {

      while (this.speed <= this.maxSpeed) {
      this.speed++;
      }
      }

      var car = new Car(100);
      car.accelerate();


    • Stephan Schulze
      am 2. August 2010 um 11:24 Uhr

      Hallo Christian,

      gerne wollte ich in dem ersten Artikel auf das Thema “prototyping” verzichten, um die Übersichtlichkeit gerade für Einsteiger zu wahren.

      Für alle Interessierten weise ich mal an dieser Stelle darauf hin, dass sich ein eigener Artikel mit dem Thema “prototyping” beschäftigen wird.

      Viele Grüße,
      Stephan


    • Christian Kaps
      am 2. August 2010 um 12:13 Uhr

      Hallo Stephan,

      ich habe das Beispiel auch nur ausgepackt weil man mit prototyping besser sieht das der Konstruktor eine eigene Methode/Funktion ist.

      Sorry wenn ich deine Planung jetzt durcheinander gebracht habe. (o;


    • Stephan Schulze
      am 2. August 2010 um 12:15 Uhr

      Hallo Christian,

      man sieht schon, dass das hier wohl eine ganze Diskussion wird – aber so soll es ja auch sein und ich bin für Anregungen jederzeit sehr dankbar.

      Und kein Grund für eine Entschuldigung ;) Ich denke, für die Leser ist es ohne Zweifel auch interessant, wo es hingeht.

      Viele Grüße und danke für die sachliche Diskussion zu diesem Thema,
      Stephan


    • molily
      am 2. August 2010 um 13:48 Uhr

      (Anscheinend ist mein letzter Kommentar nicht durchgekommen?)

      Wer etwas tiefer in JavaScript-OOP einsteigen will, dem sei meine Textreihe Organisation von JavaScripten empfohlen:
      http://molily.de/weblog/javascript-organisation

      Dort speziell der Artikel über Konstruktoren, Prototypen und Instanzen:
      http://molily.de/js/organisation-instanzen.html

      Die Einleitung erklärt, was JavaScript-OOP von z.B. PHP unterscheidet und welche Konzepte fortgeschrittenes JavaScript prägen:
      http://molily.de/js/organisation-ueberblick.html


    • Timo Reitz
      am 2. August 2010 um 21:12 Uhr

      Wenn ich mir die Funktion articleAdviseController so anschaue… was ist denn aus „Tell, don’t ask!“ geworden? Die ID wird doch nur übergeben, um dann von einem Objekt document (wo kommt das her*?) etwas zu holen. Wäre ein Beispiel, welches stattdessen direkt das Element bekommt, nicht besser gewesen? Oder noch besser: Direkt das style-Objekt, der Rest wird gar nicht benutzt.

      Immerhin sollen diese Funktionen ja beispielhaft sein und sollten daher möglichst sauber sein.

      * Rhetorische Frage, ich weiß, was das ist. ;-)


    • Kim
      am 3. August 2010 um 09:16 Uhr

      Mini-Kritik an einem Detail:

      Ich lese
      “// Instanzierung, z.B. im HEAD-Bereich der Seite”

      Javascript sollte, wenn möglich, nie im Headbereich einer Seite stehen.


    • Juan M.
      am 3. August 2010 um 13:46 Uhr

      warum das Rad neu erfinden? ;)

      http://www.prototypejs.org/api/class/create


    • Timo Reitz
      am 3. August 2010 um 17:01 Uhr

      An Juan M.: Weil es definitiv besser ist, zuerst eine Sprache zu verstehen, bevor man Frameworks einsetzt, die darauf aufbauen? ;-)


    • hakre
      am 4. August 2010 um 13:58 Uhr

      kann auch handy sein:

      function SomeName()
      {
      var self = this; // assign reference to current object to “self”

      }

      zur weiteren verwendung in methoden der klasse.

      http://www.klauskomenda.com/code/javascript-programming-patterns/


    • private und public function mit Javascript | Digital entwickelt.
      am 23. November 2011 um 10:04 Uhr

      [...] Ja, das geht. Als ich gerade im phphatesme-Blog den Artikel über objektorientiertes JavaScript [1] gelesen habe, dachte ich an ein Code-Snippet, das ich mir vor einigen Wochen zurechtgelegt hatte. [...]

    RSS Feed für Kommentare zu diesem Artikel. TrackBack URL

    Hinterlasse einen Kommentar

    Werbung
    PHP Magazin
    Ausgabe 02/2010

    Dieses Mal mit Artikeln zu den Themen OpenSocial und Apache Shindig, Graphentheorie, Smarty3

    t3n
    Ausgabe 19

    Social Media (R)evolution. Weitere Themen sind noSQL, Crowdsourcing ...

    PHP Journal
    Ausgabe 2/2010

    PHP & Windows optimal nutzen, die besten PHP-CMS im Überblick, Google-API mit Zend Framework nutzen.

    Wir wurden schon öfters gefragt, ob man uns nicht irgendwie unterstützen kann. Die Antwort war immer einfach: Klar! Am einfachsten ist es eure nächsten Einkäufe bei Amazon über unsere Link abzuwickeln. Damit würdet ihr uns schon sehr helfen. Über Co-Autoren freuen wir uns aber noch mehr.