praxisorientierte nutzung von prototypen in javascript am beispiel von jquery

Upload: robertschweda

Post on 07-Jan-2016

6 views

Category:

Documents


0 download

DESCRIPTION

Diese Seminararbeit behandelt in fünf Kapiteln die prototypenbasierte Programmierung in JavaScript. Der Schwerpunkt liegt neben der theoretischen Einordnung des Begriffs "Prototyp" auf dem praktischen Einsatz dieses Programmierparadigmas zur Realisierung bekannter Eigenschaften der klassenbasierten Objektorientierung wie z.B. Vererbung.Die konkrete Untersuchung der Praxistauglichkeit erfolgt am Beispiel der bekannten Bibliothek jQuery.

TRANSCRIPT

  • Seminararbeit im Kurs 1908OOP-Sprachen und -Konzepte

    Thema: Praxisorientierte Nutzung vonPrototypen in JavaScript am Beispiel

    von jQuery

    Autor: Robert SchwedaMatrikelnummer: 8802440

    Fernuniversitat Hagen

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript ii

    Inhaltsverzeichnis

    1 Einleitung 1

    2 Prototypenbasierte Programmierung 12.1 Historische Einordnung . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.2 Prototypen in der objektorientierten Programmierung . . . . . . . . . . 22.3 Eigenschaften protoypenbasierter Programmiersprachen . . . . . . . . . 3

    2.3.1 Fehlen von Klassen und Konstruktoren . . . . . . . . . . . . . . 32.3.2 Slots und Parent-Slot . . . . . . . . . . . . . . . . . . . . . . . . 32.3.3 Delegation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3.4 Vielfalt prototypenbasierter Programmiersprachen . . . . . . . . 5

    3 Prototypen in JavaScript 63.1 Geschichte JavaScripts . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    3.1.1 ECMAScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.1.2 JavaScript als missverstandene Sprache . . . . . . . . . . . . . . 73.1.3 JavaScript heute . . . . . . . . . . . . . . . . . . . . . . . . . . 7

    3.2 Objekte in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2.1 Objektliterale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.2 Konstruktoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.3 Klonung und Erweiterung . . . . . . . . . . . . . . . . . . . . . 10

    3.3 Prototype-Eigenschaft . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.3.1 Object.prototype . . . . . . . . . . . . . . . . . . . . . . . . . . 103.3.2 [[Prototype]] und Konstruktoren . . . . . . . . . . . . . . . . . . 11

    3.4 Delegation in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . 113.5 Vererbung in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . 13

    3.5.1 Pseudo-klassenbasierte Vererbung . . . . . . . . . . . . . . . . . 143.5.2 Prototypenbasierte Vererbung . . . . . . . . . . . . . . . . . . . 153.5.3 Mischformen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.5.4 Mixins als Alternative . . . . . . . . . . . . . . . . . . . . . . . 18

    4 JavaScript in der Praxis 184.1 Das jQuery-Projekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194.2 Untersuchung ausgewahlter Quelltextpassagen . . . . . . . . . . . . . . 22

    4.2.1 Initialisierung des jQuery-Objekts . . . . . . . . . . . . . . . . . 224.2.2 Verwendung von Prototypen . . . . . . . . . . . . . . . . . . . . 244.2.3 Weitere Besonderheiten im Entwurf . . . . . . . . . . . . . . . . 244.2.4 Praxisbeispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    5 Zukunftige Entwicklung und Fazit 26

    6 Anhang 27

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 1

    1 Einleitung

    Diese Seminararbeit entstand im Rahmen des Kurses1908 - OOP-Sprachen und -

    Konzepte an der Fernuniversitat Hagen, und beschaftigt sich mit der prototypenba-sierten Programmiersprache JavaScript. Nach einer kurzen theoretischen Betrachtungdes Prototypenbegris und der prototypenbasierten Programmierung im Allgemeinen,befasst sich der Hauptteil der Arbeit in den Kapiteln 3 und 4 mit einer konkretenImplementierung einer solchen Sprache in Form von JavaScript und ihrem praktischenEinsatz in Form der jQuery Bibliothek.

    2 Prototypenbasierte Programmierung

    Bevor das Themengebiet der prototypenbasierten Programmierung genauer untersuchtwird, soll zunachst die Entstehung des Begris

    Prototyp vorgestellt werden. Inter-

    essierte Leser finden hierzu in [1] eine ausfuhrliche Ausarbeitung, die im nachsten Ab-schnitt kurz zusammengefasst wird.

    2.1 Historische Einordnung

    Die objektorientierte Programmierung ist eng mit dem Begri der Klasse verknupft.Der Ursprung der Kategorisierung und des Klassenbegris selbst findet sich bereits inder Antike bei Platon wieder. Platon unterscheidet zwischen zwei Arten von Objekten,zum einen Objekte, die Eigenschaften von Dingen beschreiben (sog. Ideen, Formen)und zum anderen real existierende Objekte, die diese Eigenschaften vereinen. Mit die-sem Sachverhalt beschreibt der griechische Philosoph im Wesentlichen die Beziehungzwischen Klassen und ihren Instanzen [2].Sein Schuler Aristoteles formulierte mit der Definitionsregel

    genus proximum et dif-

    ferentia specifica die Prinzipien der Generalisierung und Spezialisierung, wie man sieauch heute in der objektorientierten Programmierung wiederfindet. Nach Aristoteleswird ein neuer Begri durch einen Oberbergri (genus proximum) und einer Mengevon Eigenschaften, die ihn von diesen abgrenzen, beschrieben (dierentia specifica) [3].Kritik an dieser Form der Kategorisierung wurde im 20. Jahrhundert durch den Philo-sophen Ludwig Wittgenstein geauert. Wittgenstein stellte fest, dass es gewisse Dingegibt, die nicht klar kategorisiert werden konnen. Als Beispiel bringt er den allgemeinenBegri des

    Spiels. Spiele verfugen uber eine Menge von Verwandtschaften, die Witt-

    genstein als Familienahnlichkeiten bezeichnet. Jedes individuelle Spiel verfugt uberEigenschaften, durch die es sich als Spiel auszeichnet, es existiert allerdings keine ge-meinsame Eigenschaft, uber die alle Spiele verfugen [4, S. 56-68].In den Siebzigerjahren setzte Elenoar Rosch die Forschung auf dem Gebiet der Fami-lienahnlichkeiten fort. Sie stellte fest, dass es Entitaten gibt, die eine Klasse besserreprasentieren als andere. Ein Singvogel ist beispielsweise ein typischerer Vertreter derKategorie Vogel als ein Pinguin oder ein Huhn. Diese klassenspezifischen Vertreterbezeichnete sie als Prototypen [5].

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 2

    2.2 Prototypen in der objektorientierten Programmierung

    Wie Objekte in der realen Welt beschrieben werden, wirkt sich unmittelbar auf den Ent-wurf von Programmiersprachen aus, die mit diesen Objekten arbeiten mussen. Wie beider Kategorisierung anhand von Klassen in der Philosophie, existiert auch im Bereichder klassenbasierten Programmierung Kritik an diesem Konzept. Die beiden wesentli-chen Punkte dabei lauten nach [6] und [7, S. 92]:

    Die Erstellung einer Klassenhierarchie ist ein kreativer Vorgang, der zu vielenverschiedenen Losungen fuhren kann. Dabei kann es sogar sein, dass eine Losung,die sich in der Theorie als besonders elegant erweist, nicht praktikabel ist.

    Der Begri der Klasse ist nicht eindeutig und reprasentiert unterschiedliche Kon-zepte. Klassen konnen mathematisch als Mengen interpretiert werden. Zugleichdienen sie der Beschreibung ihrer Instanzen und bieten auerdem Mechanismenzur Erzeugung dieser konkreten Vertreter.

    In den achtziger Jahren befassten sich Wissenschaftler damit Alternativen zur klas-senbasierten Programmierung zu erforschen und fokussierten sich dabei unter anderemauf die Verwendung von Prototypen. Je nach Forschungsschwerpunkt variiert die Defi-nition des Begris in den unterschiedlichen Veroentlichungen. Anlehnend an [7, S. 92]wird in dieser Arbeit ein Prototyp als ein bereits vorgefertigtes, strukturiertes Objektmit Eigenschaften und einem Verhalten aufgefasst, das bei Bedarf als Vorlage fur dieErstellung eines neuen Objektes herangezogen werden kann.Ein anschauliches Beispiel fur diese Definition bietet Lieberman in [8]: Nehmen wiran, wir kennen einen ganz bestimmten Elefanten namens Clyde (weil wir z.B. Tierpfle-ger im ortlichen Zoo sind), dann konnen wir unser Wissen uber Clyde dazu nutzen,Aussagen uber einen anderen Elefanten, namentlich Fred, zu treen. Wir konnen bei-spielsweise sagen, dass Fred grau ist und vier Beine hat.1

    Die Vorteile, die sich aus der Verwendung von Prototypen statt Klassen ergeben, lautennach [9]:

    Es handelt sich um einen naturlicheren Ansatz, da man bei der Losung vonProblemen haufig versucht, von einem konkreten Fall ausgehend eine abstrakteLosung zu finden. Die Nutzung von Prototypen spiegelt diese Vorgehensweise aufder Ebene der Programmierung wider.

    Eine flexiblere Nutzung von Objekten wird ermoglicht, da Anderungen an ein-zelnen Objekten nicht alle anderen Instanzen dieses Typs betreen.

    Klassen werden oft als komplex und einschrankend empfunden. Beispielsweisewerden in der Programmierung von grafischen Oberflachen haufig gleichartigeElemente benotigt, die sich nur marginal (z.B. in der Eventverarbeitung) von-einander unterscheiden. Trotz der geringen Dierenzen musste fur jedes dieserElemente gleich eine neue Klasse definiert werden.

    1Die Tatsache, das Fred nicht grau ist oder uber eine unnaturliche Anzahl an Beinen verfugen konnte,ignorieren wir an dieser Stelle und verweisen auf die Abschnitte 2.3.3 und 3.4.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 3

    2.3 Eigenschaften protoypenbasierter Programmiersprachen

    Bevor im nachsten Kapitel mit JavaScript eine Implementierung einer prototypenba-sierten Sprache untersucht wird, sollen in diesem der Teil Arbeit zunachst typische Ei-genschaften einer solchen Sprache vorgestellt werden. Dabei ist zu beachten, dass nichtjede Sprachimplementierung zwingend uber alle vorgestellten Merkmale verfugen muss.Die erste prototypenbasierte Programmiersprache uberhaupt war Self, die 1986 vonDavid Unger und Randall B. Smith entwickelt wurde, und die nachfolgend erlautertenSpracheigenschaften allesamt implementierte [10].

    2.3.1 Fehlen von Klassen und Konstruktoren

    Charakteristisch fur die prototypenbasierte Programmierung ist das Fehlen von Klas-sen, das allerdings nicht automatisch den Wegfall aller klassenbasierter Konzepte, wiez.B. der Vererbung, zur Folge hat. Durch den hohen Grad an Flexibilitat der proto-typenbasierten Sprachen konnen diese Mechanismen haufig simuliert werden. In Ab-schnitt 3.5 werden beispielsweise gleich mehrere Varianten zur Realisierung von Verer-bung in der Sprache JavaScript vorgestellt.Mit dem Begri der Klasse fallt auch die Moglichkeit der Erzeugung von Instanzendurch Konstruktoren weg. Es stellt sich nun die Frage, wie konkrete Objekte stattdes-sen erzeugt werden konnen? Hierzu benennt die Literatur verschiedene Moglichkeiten[10, 7, S. 84 .]:

    Klonung und Erweiterung existierender Objekte: Bei der Erzeugung einesneuen Objektes durch Klonung wird ein bereits existierendes Objekt als Vorlagefur ein neues Objekt herangezogen. Es wird neben dem Verhalten auch der Zu-stand des Ursprungsobjektes (parent) auf den Klon (child) ubertragen.Eine Spezialform des Klonens stellt die Erweiterung dar. Sie ermoglicht es, einkonkretes Objekt durch die Benennung eines Ursprungsobjektes und einer Mengevon weiteren Eigenschaften und Unterschieden zu erstellen.

    Erzeugung ex nihilo: Bevor Objekte geklont oder erweitert werden konnen,muss allerdings mindestens ein konkretes Objekt existieren. Dies kann bereitsdurch die Laufzeitumgebung der Sprache bereitgestellt oder ex nihilo vom Pro-grammierer erstellt werden. Unter Letzterem versteht man typischerweise eineBeschreibung eines Objektes durch Benennung und Belegung seiner Eigenschaf-ten und seines Verhaltens an Ort und Stelle der Verwendung.

    2.3.2 Slots und Parent-Slot

    Objekte werden in prototypenbasierten Sprachen als eine Menge von sog. Slots auf-gefasst.2 Ein Slot meint dabei ein einfaches Schlussel-Wert-Paar (key-value-pair), ent-spricht also der Datenstruktur der Map. Der Zugri auf einen Wert, der sowohl Daten(Zustand des Objekts) als auch Funktionen (Verhalten des Objekts) beinhalten kann,erfolgt uber einen Schlussel [7, S. 96 f.].In einigen Sprachen verfugen Objekte uber einen speziellen Slot, den sog. Parent-Slot.

    2Der Begri des Slots stammt aus dem Bereich der kunstlichen Intelligenz und bezeichnet einfacheine Menge von Daten, die zu einer bestimmten Situation (frame) gehoren. Siehe [11] fur weitereInformationen.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 4

    Dieser Slot beihnaltet eine Referenz auf den Prototypen des Objektes, also das Objekt,das beim Klonen also Vorlage diente. Der Parent-Slot spielt eine entscheidende Rolle

    Abbildung 1: Schematische Darstellung eines Objektes mitn+1 Slots, Quelle: Eigene Darstellung

    bei der Realiserung der sog. Delegation, die im nachsten Abschnitt theoretisch erlautertund in Abschnitt 3.4 an praktischen Beispielen in der Programmiersprache JavaScriptdemonstriert wird [10].

    2.3.3 Delegation

    In der klassenbasierten Programmierung entsprechen Klassen Bauplanen fur Objekte.Eine Klasse definiert dabei eine Menge von Attributen, uber die jede ihrer Instanzenverfugt. Die Belegung dieser Attribute mit konkreten Werten geschieht individuell aufder Ebene der Instanzen d.h. jede Instanz verfugt uber ihren eigenen Zustand.3

    Klassen definieren daruber hinaus das Verhalten ihrer zukunftigen Instanzen. An-derungen am Verhalten der Klasse haben zur Folge, dass sich das Verhalten aller kon-kreten Objekte dieser Klasse andert. Mochte man ein Objekt erzeugen, dass sich durchzusatzliche Attribute oder ein besonderes Verhalten auszeichnet, so muss eine Speziali-sierung in Form einer Subklasse erzeugt werden, die alle Eigenschaften der Basisklasseerbt und um zusatzliche Eigenschaften erweitert wird [8, 7, S. 94 .].Eine Alternative zur klassenbasierten Vererbung bieten prototypenbasierte Sprachenin Form der sog. Delegation. Erhalt ein Objekt in einer Programmiersprache, die De-legation unterstutzt, eine Nachricht wie z.B. den Abruf einer Eigenschaft, so versuchtes zunachst selbst diese Nachricht zu beantworten. Ist dies nicht moglich, so wird dieNachricht an das Objekt im Parent-Slot des empfangenden Objektes weitergeleitet.Dieser Vorgang kann nun solange wiederholt werden bis die Eigenschaft in einem derDelegaten gefunden wird, oder das Ende der Kette erreicht wird. Mochte nun ein Kind-Objekt einen Attributwert andern, der von seinem Prototypen-Objekt stammt, reichtes aus diesen Wert lokal im Kind-Objekt zu setzen.Dieser Sachverhalt soll noch einmal in Abbildung 2 verdeutlicht werden. Clyde ist derPrototyp von Fred, da Freds Parent-Slot uber eine Referenz auf das Objekt von Clydeverfugt. Wird nun Fred nach der Anzahl seiner Stozahne gefragt, so wird die Anfrageimplizit an Clyde delegiert, der als Prototyp von Fred mit

    2 antwortet. Wird Fred

    wiederum nach seinem Namen gefragt, muss die Anfrage nicht weitergeleitet werden,da er selbst uber einen Slot mit entsprechendem Schlussel verfugt.

    3Mit Hilfe von statischen Variablen kann in den meisten klassenbasierten Sprachen auch ein gemein-samer Zustand erzeugt werden.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 5

    Abbildung 2: Schematische Darstellung der Delegation,Quelle: Eigene Darstellung

    In Abschnitt 3.4 wird gezeigt, wie der Mechanismus der Delegation in JavaScript ge-nutzt werden kann, um Vererbung zu simulieren. Der umgekehrte Fall ist allerdingsnicht moglich. Dies liegt an den unterschiedlichen Arten, wie in den prototypen- undklassenbasierten Sprachen mit der Selbstreferenz self bzw. this umgegangen wird.In klassenbasierten Sprachen bezieht sich die Variable self immer auf den Empfanger

    Abbildung 3: Forwarding vs. Delegation,Quelle: http://bit.ly/1yGzr2y

    eines Methodenaufrufes. Man nennt diese Art von Aufruf auch Forwarding.4 Es ist alsonicht moglich Methoden so aufzurufen, dass self ein anderes Objekt referenziert. DieDelegation der prototypenbasierten Sprachen ermoglicht dies hingegen, da die Variableself in diesem Fall nicht den Aufgerufenen (Client), sondern den Aufrufer (Server)referenziert. Neben dem Zustand kann so auch das Verhalten des Prototypen wieder-verwendet werden [8].

    2.3.4 Vielfalt prototypenbasierter Programmiersprachen

    Am Ende dieses Kapitels soll kurz anhand der beiden Sprachen Kevo und Omegaverdeutlicht werden, dass die vorgestellten Eigenschaften nicht notwendigerweise furalle Implementierungen prototypenbasierter Sprachen gelten.

    Kevo: Die Programmiersprache Kevo verfugt weder uber einen Parent-Slot nochden Mechanismus der Delegation. Wird ein Objekt geklont, so wird eine un-abhangige Kopie, die in keinerlei Beziehung zum Parent steht, erzeugt. Es stehtdem Entwickler danach frei beliebige Anderungen an dem neu erzeugten Objektdurchzufuhren. Objekte konnen zudem in Gruppen zusammengefasst werden, dieebenfalls durch sog. modifications verandert werden konnen [7, S. 100 .].

    Omega: Beim Entwurf der Sprache Omega wurde Wert auf Typsicherheit ge-legt. Man entschied sich daher fur die Nutzung einer statischen Typprufung in

    4In der klassenbasierten Programmierung werden die Begrie Delegation und Forwarding haufigsynonym verwendet. Gemeint ist meist Letzeres, siehe [12, S. 116 f.].

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 6

    Kombination mit klassischer Vererbung. Objekte konnen in einem Objektbrow-ser erzeugt und von bereits existierenden Objekten abgeleitet werden. Prototypendienen in Omega daher zusatzlich der Definition von Interfaces, da abgeleiteteObjekte sicherstellen mussen, dass das Interface des Prototypen eingehalten wird[13, 7, S. 104].

    3 Prototypen in JavaScript

    In diesem Kapitel wird die konkrete Implementierung einer prototypenbasierten Pro-grammiersprache anhand der weit verbreiteten Sprache JavaScript vorgestellt. Im ers-ten Teil wird die Geschichte JavaScripts kurz vorgestellt. Nach einem kurzen Exkurszum Objektbegri beschaftigt sich der Hauptteil dieses Kapitels mit dem Konzept desPrototypen, sowie der Delegation und Vererbung.

    3.1 Geschichte JavaScripts

    Die Programmiersprache JavaScript wurde im Jahr 1995 von Brendan Eich, einemdamaligen Mitarbeiter des Unternehmens Netscape Communications, erfunden undumgesetzt. Eine Besonderheit dieser Sprache ist die Tatsache, dass Eich sie in in weni-gen Tagen entwickelt hat, und sie dennoch bis heute weitergenutzt wird [14].Eich bediente sich dabei an Sprachkonzepten, die er fur besonders nutzlich empfand.Anders als der Name der Sprache vermuten lasst, wurde er nicht durch die SpracheJava, sondern durch die prototypenbasierte Sprache Self und die funktionalen SprachenScheme bzw. Lisp inspiriert. Seine Implementierung fand im selben Jahr Einzug in denNetscape Navigator,5 und wurde bereits ein Jahr spater von Microsoft kopiert und alsJScript im Internet Explorer angeboten [15, S. 1, 14].

    3.1.1 ECMAScript

    Die alternativen Implementierungen der Sprache fuhrten zum sog. Browserkrieg undder damit verbundenen Problematik der konkurrierenden DHTML-Implementierungen.Da jeder Browser uber eigene Features und Interfaces verfugte, mussten Entwicklerhaufig browser-spezifischen Quelltext schreiben. Um den Inkompatibilitaten und derresultierenden Doppelbelastung entgegenzuwirken, meldete der Microsoft Konzern be-reits 1996 eine Spezifikation der Sprache beim European Computer ManufacturersAssociation (ECMA) an. Rechtsstreitigkeiten fuhrten dazu, dass der verabschiedeteStandard weder Java- noch J-, sondern ECMAScript6 hie [15, S. 2].Die relevanten Versionen von ECMAScript sind die Versionen 3 und 5, die 1999 und2009 verabschiedet wurden, und die Sprache um wichtige Features wie z.B. RegularExpressions und den Strict mode erweitert haben [16].In diesem Dokument wird der Begri JavaScript synonym zur Implementierung derECMAScript Version 5.1 verwendet. Sollte eine andere Version des Standards gemeintsein, so wird an der jeweiligen Stelle explizit darauf hingewiesen.

    5Damals noch unter dem Namen LiveScript.6Laut Brendan Eich war die Einigung auf diesen Namen noch tragischer als die trugerische Bezeich-nung JavaScript, da ECMA nach einer Hautkrankeit klinge.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 7

    3.1.2 JavaScript als missverstandene Sprache

    Douglas Crockford, der mit seinem WerkJavaScript - The Good Parts, mageblich

    an der Verbesserung von JavaScripts Ruf beteiligt war, bezeichnet unter [17] JavaScriptals die am meisten missverstandenste Programmiersprache.

    Am meisten bezeichnet

    dabei nicht nur die Anzahl der Missverstandnisse selbst, sondern auch die groe Mengean Entwicklern, die die Sprache missverstehen. Letzeres liegt vor allem an der groenVerbreitung der Sprache, die von vielen modernen Browsern interpretiert werden kann.Die beiden wichtigsten Missverstandnisse lauten:

    Namensgebung: Der Name der Programmiersprache lasst auf eine Verwandt-schaft mit der objektorientierten und vor allem klassenbasierten Sprache Ja-va schlieen. Leider haben die beiden Sprachen auer der C-ahnlichen Syntaxkeine Gemeinsamkeiten. Die Bezeichnung JavaScript ist ein reiner Marketing-Schachzug gewesen, der die Sprache popularer machen sollte [14]. Die Tatsache,dass der Sprachstandard ECMAScript heit und es diverse Implementierungengibt (JavaScript, ActionScript, JScript) tat ihr Restliches, um zur allgemeinenVerwirrung beizutragen.

    Unbekannte Konzepte: Das Konzept der funktionalen Programmierung istvielen Entwicklern einfach nicht vertraut. Hinzu kommt, dass die Prinzipien derobjektorientierten Programmierung zwar durchaus bekannt sind, aber die meis-ten Sprachen doch auf klassenbasierte Implementierungen setzen. Es ist also nichtverwunderlich, wenn viele Entwickler schon fast krampfhaft versuchen JavaScriptdie Idee der Klassen aufzudrucken. Die irrefuhrende Terminologie des sog. Kon-struktors (siehe Abschnitt 3.2.2) ist nicht minder unbeteiligt am Durcheinander[18, S. 90-94].

    3.1.3 JavaScript heute

    Heute stellt der Browser weiterhin die Hauptdomane JavaScripts dar, dabei wird dieSprache durch viele Bibliotheken erganzt, die dem Webdesigner bei seiner taglichen Ar-beit behilflich sind, und die Dierenzen der verschiedenen Browser-Implementierungennivellieren. Mit jQuery wird in Kaptitel 4 eine solche Bibliothek vorgestellt.Im Jahr 2009 hat JavaScript den Sprung aus dem Browser hinaus geschat und kannseit dem universell d.h. auf Client- und Serverseite verwendet werden. Mit node.js schufder Entwickler Ryan Dahl ein Framework, das sich durch hohe Performanz auerhalbdes Browsers auszeichnet.Mit ECMAScript Version 6 befindet sich die nachste Novelle des Sprachstandards be-reits in der Entwicklung.7

    3.2 Objekte in JavaScript

    JavaScript verfugt neben den primitiven Datentypen Number, String und Boolean,den besonderen Typen undefined und null uber Objekte. Zwei besondere Objekte,die durch die verschiedenen Laufzeitumgebungen bereitgestellt werden, sind Funkti-onsobjekte (Function) und Felder (Array) [15, S. 29]. Der Aufbau eines Objektes

    7Stand November 2014

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 8

    orientiert sich dabei an dem bereits beschrieben Konzept der Slots, die in JavaScriptProperties und im weiteren Verlauf der Arbeit einfach Eigenschaften oder Attributegenannt werden. Ein solches Attribut besteht dabei aus einem Schlussel-Wert-Paar,wobei der Schlussel stets vom Typ String sein muss, wahrend der Wert einen beliebi-gen Datentypen annehmen kann [19, S. 48, 15, S. 115].Da JavaScript frei von Klassen ist, mussen Objekte auf andere Arten erstellt werdenkonnen, dabei unterscheidet die Sprache insgesamt vier unterschiedliche Arten der Ob-jekterzeugung, die in den nachsten Unterkapiteln vorgestellt werden sollen.

    3.2.1 Objektliterale

    Die einfachste Form der Erstellung von Objekten ist ex nihilo in Form sog. Objekt-literale, die eine Erzeugung an Ort und Stelle ermoglichen. Auf diese Art und Weisekonnen Zustand und Verhalten eines Objektes vollstandig definiert werden [20, S. 21].Die dabei verwendete Notation nennt sich JavaScript Object Notation (JSON ), undwird im Bereich der Webtechnologie haufig zur Serialisierung von Daten verwendet[21].

    Listing 1: Objekterzeugung mittels Objektliteral

    1 var clyde = {2 name : "Clyde",3 numberOfTusks : 2,4 makeNoise : function () {5 console.log("Tooeroooe!");6 }7 }89 console.log(clyde.name); // "Clyde"10 console.log(clyde["numberOfTusks"]); // 211 clyde.makeNoise (); // "Tooeroooe !"

    In Listing 1 wird ein Objekt namensClyde erstellt, das neben den beiden Eigen-

    schaften name und numberOfTusks uber die Funktion8 makeNoise verfugt. Die Zeilen9 und 10 des Beispiels zeigen die beiden Arten des Zugris auf die Eigenschaften ei-nes Objektes. Dabei ist der Zugri mittels sog. Dot-Notation (Zeile 9) aquivalent zumZugri uber den Schlussel (Zeile 10), wobei sich Letzterer besonders gut fur reflektiveAufrufe eignet.

    3.2.2 Konstruktoren

    Neben den Objektliteralen ist eine Objekterzeugung mittels sog. Konstruktoraufrufmoglich. Konstruktoren sind gewohnliche Funktionen, deren Name per Konventiongro geschrieben wird. Eine Funktion wird allerdings erst als Konstruktor verwendet,wenn sie mit dem Schlusselwort new aufgerufen wird.

    8Man konnte genau so gut von einer Methode sprechen. Da in JavaScript jede Funktion zu einemObjekt gehort (im Zweifelsfall zum sog. globalen Objekt) ist jede Funktion gleichzeitig auch ei-ne Methode. Um den funktionalen Charakter der Sprache zu unterstreichen, verwende ich denAusdruck Funktion.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 9

    Listing 2: Objekterzeugung mittels Konstruktoraufruf

    1 function Elephant(name) {2 this.name = name;3 this.numberOfTusks = 2;4 this.makeNoise = function () {5 console.log("Tooeroooe!");6 }7 }89 var clyde = new Elephant("Clyde");10 clyde instanceof Elephant; // true

    Analog zum vorherigem Beispiel wird in Listing 1 ein Objekt namensClyde erzugt,

    allerdings erkennt man am Schlusselwort new in Zeile 9, dass ein Konstruktoraufruf zurErzeugung verwendet wird. Ein solcher Aufruf hat eine Menge von Operationen zurFolge, die auf den ersten Blick nicht ersichtlich sind und daher an dieser Stelle nocheinmal einzeln aufgeschlusselt werden sollen [18, S. 21, 22]:

    1. Es wird ein neues (leeres) Objekt erstellt.

    2. Die Prototypen-Eigenschaft des Objektes wird gesetzt. Was dies konkret bedeu-tet, und welcher Wert der Eigenschaft zugewiesen wird, wird detailliert in Kapitel3.3 erlautert.

    3. Die Variable this referenziert das neue Objekt und ermoglicht so eine Modifika-tion seiner Eigenschaften.

    4. Sollte die Konstruktorfunktion keinen explizit Ruckgabewert benennen, so wirddas neue Objekt zuruckgegeben.

    Das Konzept der Konstruktoren wird haufig kritisiert. Konstruktoren erwecken durchihren Namen und ihre Syntax den Eindruck JavaScript verfuge uber Klassen. Die Ver-wendung des Schlusselwortes new in Kombination mit Zuweisungen an die Variablethis innerhalb der Konstruktorfunktionen erinnern stark an die Verwendung von Kon-struktoren in klassenbasierten Sprachen wie Java oder C#, und fuhren bei unerfahrenenProgrammierern und JavaScript-Anfangern zu vermeidbaren Verstandnisproblemen.An dieser Stelle sei zudem noch einmal erwahnt, dass Konstruktoren gewohnliche Funk-tionen sind, die auch ohne das Schlusselwort new aufgerufen werden konnen. Leiderwird in diesem Fall die Selbstreferenz this an das globale Objekt gebunden, was unterUmstanden zu schwer nachvollziehbaren Fehlern fuhren kann (siehe Listing 3).Die Konsequenz ist, dass einige Autoren von der Verwendung von Konstruktoraufrufenabraten und stattdessen dazu appellieren, die ubrigen Formen der Objekterzeugung zunutzen, die charakteristisch fur prototypenbasierte Sprachen sind [20, S. 30].

    Listing 3: Fehlerhafte Objekterzeugung

    1 function Elephant(name) {2 this.name = name;3 }45 var clyde = Elephant("Clyde"); // new fehlt6 console.log(clyde.name) // Fehler7 console.log(window.name) // "Clyde"

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 10

    3.2.3 Klonung und Erweiterung

    In Abschnitt 2.3.1 haben wir bereits die Moglichkeit der Objekterzeugung durch Klo-nung bzw. Erweiterung kennengelernt. ECMAScript verfugt seit Version 5.1 uber dieFunktion Object.create, die beide Arten der Objekterzeugung ermoglicht. Da auchObject.create ausgiebig Gebrauch von Prototypen macht, wird an dieser Stelle aufdie ausfuhrliche Erlauterung verzichtet und auf die spatere Betrachtung in Kapitel 3.5.2verwiesen.

    3.3 Prototype-Eigenschaft

    Im vorherigen Kapitel wurde bereits mehrfach die sog. Prototyp-Eigenschaft einesObjektes angesprochen. Diese spezielle Eigenschaft referenziert ein weiteres Objekt,namlich seinen sog. Prototypen. In JavaScript entsprechen Prototypen dem bereitsvorgestellte Konzept des Parent-Slots, das bereits am Beispiel von Self erlautert wur-de. Die Bedeutung des Begris

    Prototyp ist in JavaScript allerdings mehrfach belegt

    und soll an dieser Stelle genauer betrachtet werden [23, S. 83, 24].

    Prototyp als Referenz auf das Elternobjekt: Der Begri Prototyp kannzum einen, wie bereits erlautert, eine Referenz auf das Elternobjekt bezeichnen.Es handelt sich dabei um eine spezielle Eigenschaft eines Objektes, die durch denECMAScript Standard spezifiziert wird. Diese Eigenschaft wird anlehnend an dieNotation des Standards auch haufig als [[Prototype]] bezeichnet.In ECMAScript 5.1 und fruher bezeichnete [[Prototype]] eine interne Eigen-schaft eines Objekts, fur die keine Zugrismethoden existierten. Einige Brow-serhersteller setzen sich in der Vergangenheit uber den Standard hinweg undermoglichten den Zugri auf das Elternobjekt uber die proprietare Eigenschaftproto . Diese Idee wurde im vorlaufigen ECMAScript 6 Standard aufgegrif-

    fen und in Form der Eigenschaft Object.prototype. proto ubernommen [25,Kap. B.2.2.1].

    Prototyp als Konstruktoreigenschaft: Funktionen verfugen uber eine zu-satzliche Eigenschaft namens prototype, auf die explizit zugegrien werden kann.Diese Eigenschaft spielt eine wichtige Rolle bei der Objekterzeugung, falls dieFunktion als Konstruktur verwendet wird. [[Prototype]] und prototype be-zeichnen im Fall von Funktionen also zwei verschiedene Eigenschaften.

    3.3.1 Object.prototype

    Wird ein Objekt mittels Objektliteral oder new Object() erzeugt, so verweist [[Proto-type]] auf einen besonderen Prototypen, namlich Object.prototype. Object.proto-type ist ein besonderes Objekt, das von der entsprechenden Laufzeitumgebung be-reitgestellt wird, und eine Menge von Standardfunktionen (z.B. toString() und is-PrototypeOf()) bereitstellt. Object.prototype ist insofern besonders, da es selbstuber keinen eigenen Prototypen verfugt [26].

    Listing 4: Object.prototype als besonderer Prototyp

    1 o = {}2 Object.getPrototypeOf(o) === Object.prototype; //true

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 11

    3 Object.getPrototypeOf(Object.prototype) === null; // true

    3.3.2 [[Prototype]] und Konstruktoren

    In Abschnitt 3.2.2 wurde bereits gezeigt, dass die Objekterzeugung mittels Konstruk-toraufruf ebenfalls Anderungen am Prototypen eines Objeks durchfuhrt. Dem neu-en Objekt, das durch den Aufruf erstellt wurde, wird als [[Prototype]] der Wertder Prototyp-Eigenschaft (.prototype) des Konstruktors zugewiesen. Anders ausge-druckt: Die interne Prototypeneigenschaft ([[Prototype]]) referenziert bei Objek-ten, die mittels Konstruktoraufruf erzeugt wurden, das selbe Objekt wie die explizitePrototypen-Eigenschaft .prototype der Konstruktor-Funktion. Listing 5 verdeutlichtdiesen Sachverhalt an einem praktischen Beispiel.

    Listing 5: Anderungen an Prototyp-Objekten

    1 function Elephant(name) {2 this.name = name;3 }45 console.log(Elephant.prototype); // {}67 Elephant.prototype.numberOfTusks = 2;8 Elephant.prototype.makeNoise = function () {9 console.log("Tooeroooe!");10 }1112 var clyde = new Elephant("Clyde");13 clyde.numberOfTusks === 2; // true14 clyde.makeNoise (); // "Tooeroooe !"15 Object.getPrototypeOf(clyde) === Elephant.prototype // true

    Es wurde bereits mehrfach erwahnt, dass Konstruktoren in JavaScript einfache Funk-tionen sind. Da Funktionen selbst

    first-class citizens, also Objekte sind, verfugen

    sie selbst auch uber Eigenschaften. Eine dieser Eigenschaften ist, die bereits erwahnteEigenschaft prototype, die in Zeile 5 zunachst auf eine leeres Objekt verweist und beiBedarf auch geandert werden kann. In den Zeilen 7-10 wird eben dieses Prototypen-Objekt modifiziert und erhalt neben einem Attribut eine neue Funktion. Wird darauf-hin ein neues Objekt mittels Konstruktoraufruf erzeugt, so sieht man (in den Zeilen 13und 14), dass dieses Objekt ebenfalls uber die Eigenschaften des Prototypen verfugt.Abbildung 4 stellt zur Verdeutlichung das resultierende Objektgeflecht noch einmalgrafisch dar.9

    3.4 Delegation in JavaScript

    Es stellt sich nun die Frage, wie im vorherigen Abschnitt ein Objekt auf die Eigenschaf-ten seines Prototypen zugreifen konnte. Dieser Mechanismus wird in JavaScript mittels

    9In Wirklichkeit handelt es sich bei dieser Grafik, die so oder so in ahnlich in vielen Lehrbuchernund auf vielen Webseiten gefunden werden kann um eine Vereinfachung des Sachverhalts. An demsimplen Aufruf Elephant() sind in Wirklichkeit mehr Objekte beteiligt, da die Funktion selbstauch uber die Eigenschaft [[Prototype]] verfugt. Fur Details siehe [27].

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 12

    Abbildung 4: Prototypen in JavaScript, Quelle: EigeneDarstellung

    Delegation realisiert und haufig auch als Prototype-Chaining bezeichnet. Wird eine Ei-genschaft eines beliebigen Objektes abgefragt, so pruft das Objekt zunachst lokal, obes uber diese Eigenschaft verfugt. Ist dies der Fall, so wird die entsprechende Operationdurchgefuhrt. Schlagt der Versuch allerdings fehl, so wird der Zugri an das Objektweitergeleitet, das mittels [[Prototype]] referenziert wird. Dieser Mechanismus wirdso lange fortgesetzt bis Object.prototype erreicht wird. Sollte auch dort die gesuch-te Eigenschaft nicht gefunden werden, so wird abgebrochen, da Object.prototypebekanntlich uber keinen weiteren Prototypen verfugt [19, S. 71].

    Listing 6: Delegation in JavaScript

    1 function Elephant(name) {2 this.name = name;3 }45 Elephant.prototype.numberOfTusks = 2;6 Elephant.prototype.makeNoise = function () {7 console.log(this.name + " says: Tooeroooe!");8 }910 var clyde = new Elephant("Clyde");11 var fred = new Elephant("Fred");1213 Elephant.prototype.eat = function () {14 console.log("nom nom nom");15 }1617 clyde.eat (); // "nom nom nom"1819 fred.numberOfTusks = 1; // poor fred ;(20 clyde.numberOfTusks === 2; // true21 fred.numberOfTusks === 1; // true2223 fred.makeNoise (); // "Fred says: Tooeroooe !";

    Wir wollen anhand des Listings 6 das Prinzip der Delegation in JavaScript noch einmalnachvollziehen. Nach der Definition des Konstruktors und der Erweiterung des Proto-

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 13

    typen werden zwei konkrete Elefanten erzeugt.In den Zeilen 13-15 wird der Prototyp der beiden Elefanten nachtraglich, d.h. nachdemdie beiden Objekte bereits erzeugt wurden, um die Funktion eat() erweitert. In Zei-le 17 wird nun die nachtraglich hinzugefugte Funktion auf einem der beiden Objekteerfolgreich aufgerufen. Dieser Sachverhalt verdeutlicht, dass es sich bei einem Proto-typen um ein gewohnliches Objekt handelt, das beliebig modifiziert werden kann. Eszeichnet sich nur als Prototyp aus, weil es durch [[Prototype]] eines beliebigen ande-ren Objektes referenziert wird. Der Mechanismus der Delegation sorgt dafur, dass diebeiden Objekte clyde und fred indirekt uber den Zustand und das Verhalten ihresPrototypen verfugen.Wir wollen nun den umgekehrten Fall betrachten und eine Eigenschaft eines bereitserzeugten Elefanten modifizieren. In Zeile 19

    verliert Fred einen Stozahn. In den bei-

    den folgenden Zeilen sieht man, dass die Zuweisung nur Auswirkungen auf das Objektfred hat. Dies erklart sich dadurch, dass die Zuweisung die Erzeugung einer neuenEigenschaft im Objekt selbst zur Folge hat, und nicht an den Prototypen delegiertwird. Das Objekt fred verfugt nun also uber einen eigenen Wert fur die EigenschaftnumberOfTusks, was zur Folge hat, dass der Mechanismus des Prototype-Chaining be-reits vorzeitig fundig wird, und die Anfrage nicht an [[Prototype]] delegiert werdenmuss. Man nennt dieses Verhalten Shadowing und es bietet den Vorteil, dass lokaleAnderungen an einem Kind eines Prototypen nicht ungewollt alle anderen Kinder desgleichen Prototypen modifizieren.Abbildung 5 stellt die beiden Objekte und die Beziehung zu ihren Prototypen nocheinmal grafisch dar.

    Abbildung 5: Delegation in JavaScript, Quelle: EigeneDarstellung

    3.5 Vererbung in JavaScript

    Bisher wurde nur die Beziehung zwischen einem Objekt und seinem Prototypen be-trachtet. Dieser einstufige Zusammenhang entspricht im Wesentlichen der Beziehungzwischen einem Objekt und seiner Klasse in der klassenbasierten Programmierung.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 14

    Es ist allerdings leicht zu erkennen, dass sich mit dem Ansatz der Delegation einemehrstufige Anordnung von verschiedenen Objekt erzielen lasst, mit der die klassenba-sierte Vererbung (implementation inheritance) simuliert werden kann. In der Literaturwerden dabei verschiedene Ansatze diskutiert, die an dieser Stelle vorgestellt werdensollen.

    3.5.1 Pseudo-klassenbasierte Vererbung

    Anhand von Listing 7 wollen wird die sog. pseudo-klassenbasierte Vererbung betrach-ten.

    Listing 7: Pseudo-klassenbasierte Vererbung

    1 function Mammal (name) {2 this.name = name;3 }45 Mammal.prototype.eat = function () {6 console.log("nom nom nom");7 }89 function Elephant(name) {10 this.name = name;11 this.numberOfTusks = 2;12 }1314 Elephant.prototype = new Mammal ();15 Elephant.prototype.makeNoise = function () {16 console.log(this.name + " says: Tooeroooe!");17 }1819 var clyde = new Elephant("Clyde");20 clyde.name === "Clyde"; // true21 clyde.numberOfTusks === 2; // true22 clyde.eat (); // "nom nom nom"23 clyde.makeNoise (); // "Clyde says: Tooeroooe !");

    Diese Form der Vererbung in JavaScript orientiert sich stark an der klassenbasiertenVererbung. Es werden zwei Konstruktoren definiert, deren Prototypen uber zusatzlicheEigenschaften verfugen. Die tatsachliche Implementierung der Vererbung findet in Zei-le 14 des Listings 7 statt. Durch das Uberschreiben der Prototyp-Eigenschaft desKonstruktors wird ein neues Objekt (ein Saugetier) erzeugt, dessen interne [[Proto-type]]-Eigenschaft auf Mammal.prototype verweist. Das entstandene Objektgeflechtist in Abbildung 6 dargestellt. Dieser haufig verwendete Ansatz wird gerne um weiterenFunktionalitaten, wie z.B abstrakten Klassen, erweitert (siehe z.B. [15, Kap. 9.7.4].Es gibt allerdings auch Kritik an dieser Art der Realisierung von Vererbung, die imWesentlichen mit der Verwendung von Konstruktoraufrufen zusammenhangt. Nebender bereits bekannten Kritik an der Mechanik des Konstruktoraufrufs in JavaScript,ist diese Variante im Entwurf unvorteilhaft. Zum einen wird durch den Aufruf newMammal() in Zeile 14 ein konkretes Saugetier erzeugt, obwohl man ja eigentlich nureinen Prototypen benotigt.10 Es findet also konzeptionell eine Vermischung zwischen

    10Elephant.prototype = Mammal.prototype; ist ubrigens auch keine Option, da dadurch alleSaugetiere zu Elefanten wurden und umgekehrt.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 15

    Abbildung 6: Pseudo-klassenbasierte Vererbung, Quelle:Eigene Darstellung

    den Objekten, die konkrete Instanzen reprasentieren, und Objekten, die Klassen re-prasentieren, statt.Auf den ersten Blick konnte man ebenfalls meinen, es fande, bedingt durch den Aufrufin Zeile 14, eine Verkettung von Konstruktoraufrufen statt. Dies erweist sich allerdingsals falsch, denn wird ein neues Objekt mit new Elephant() erstellt, so wird keineswegsder Konstruktor des Saugetiers (Zeile 1) aufgerufen, stattdessen mussen die geerbtenAttribute in der Konstruktorfunktion der

    Subklasse wiederholt werden (Zeile 10).11

    Der Konstruktor des Saugetiers wird in Listing 7 lediglich einmal zur Erzeugung desPrototypenobjektes ausgefuhrt. Da zum Zeitpunkt des Aufrufs auch keine sinnvol-len Daten zur Verfugung stehen, werden auch keine Argumente an den Konstruktorubergeben. Dies kann zusatzlich zu unvorhergesehenen Komplikationen fuhren, wennder Konstruktor sinnvolle Werte fur seine korrekte Ausfuhrung benotigt [20, S. 48, 18,S. 102].

    3.5.2 Prototypenbasierte Vererbung

    Bis zur Freigabe des ECMAScript Standards in der Version 5.1 war die im vorheri-gen Abschnitt vorgestellte Methode die bevorzugte Art und Weise Vererbung in Java-Script zu simulieren. Mit der genannten Version des Standards wurde die FunktionObject.create() eingefuhrt, die einen naturlicheren Weg zur Realisierung von Verer-bung ermoglicht. Die Funktion ermoglicht eine Vererbung unter Objekten, unabhangigvon Klassenobjekten und Konstruktoren, durch Klonung und Erweiterung existierenderObjekte. Sie wird wahlweise mit einem oder mit zwei Argumenten aufgerufen, wobeidas erste Argument stets das bereits vorhandene Objekt erwartet, das der [[Proto-type]]-Eigenschaft eines neu erzeugten Objektes zugewiesen werden soll [18, S. 109f.]. Die Funktionsweise soll an Listing 8 nachvollzogen werden.

    Listing 8: Object.create Polyfill

    1 if (typeof Object.create !== 'function ') {2 Object.create = function (o) {

    11In Abschnitt 3.5.3 wird gezeigt, wie man zumindest diese Unschonheit beseitigen kann.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 16

    3 function F() {}4 F.prototype = o;5 return new F();6 };7 }89 newObject = Object.create(oldObject);

    Listing 8 zeigt eine mogliche Implementierung der Methode Object.create() undgleichzeitig einen sog. Polyfill, einen Quelltext, der dazu dient Browserinkompatibi-litaten zu schlieen, indem eine proprietare Funktionalitat mit bereits standardisiertenMitteln nachgestellt wird. In diesem konkreten Fall handelt es sich um eine Imple-mentierung, die eine eingeschrankte Version von Object.create() bereitstellt [23, S.91, 20, S. 22]. In Zeile 3 wird ein temporarer Konstruktor erstellt, dessen prototype-Eigenschaft im nachsten Schritt mit dem ubergebenen Objekte o uberschrieben wird.Zeile 5 hat zur Folge, dass ein neues Objekt zuruckgegeben wird, dessen [[Proto-type]]-Eigenschaft auf das ubergebene Objekt o verweist.12

    Die standardisierte Implementierung der Funktion bietet zusatzlich die Moglichkeit ei-ne Menge von Eigenschaften, in Form eines weiteren Parameters, zu ubergeben, umdie das neue Objekt erweitert wird.

    Listing 9: Klonung und Erweiterung von Objekten

    1 var clyde = { name : "Clyde", numberOfTusks : 2 }23 // "cloning"4 var fred = Object.create(clyde);5 fred.name = "Fred";6 fred.numberOfTusks === 2; //true7 fred.african = true;89 // extending10 var bonnie = Object.create(fred , {11 isMatriarch: {12 configurable: true ,13 enumerable: true ,14 value: true ,15 writable: true16 },17 name: {18 configurable: true ,19 enumerable: true ,20 value: "Bonny",21 writable: true22 }23 });2425 bonnie.name === "Bonny"; // true26 bonnie.isMatriarch === true; // true

    Im Listing 9 wird Object.create() verwendet, um eine mehrstufige Beziehung zwi-schen Objekten zu realisieren. Die Zeile 4 zeigt die Verwendung der Funktion zur

    12Laufzeitumgebeungen, die ECMAScript 5.1 unterstutzen, bieten naturlich native Implementierun-gen dieser Funktion an.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 17

    Klonung eines existierenden Objektes. In den Zeile 10-23 erfolgt eine Erweiterung, deszuvor erstellen Klons, um die Eigenschaft isMatriarch. Die Erlauterung der Notationzur Erweiterung eines Objektes (configurable, enumerable usw.) wurde an dieserStelle den Rahmen der Arbeit sprengen. Es ist lediglich darauf hinzuweisen, dass dieEigenschaft value den tatsachlichen Wert, den die neu hinzugefugte Eigenschaft er-halten soll, enthalt. Zusatzlich wird der Wert des bereits vorhandenen Attributs namein den Zeilen 17-21 uberschrieben.Diese Form der Vererbung wird auch haufig dierentielle Vererbung genannt und er-laubt in JavaScript sogar das Entfernen vorhandener Attribute. Das resultierende Ob-jektgeflecht wird in Abbildung 7 gezeigt.

    Abbildung 7: Prototypenbasierte Vererbung, Quelle: EigeneDarstellung

    3.5.3 Mischformen

    In der jungeren Literatur zu JavaScript finden sich zunehmend Mischformen aus denbeiden vorgestellten Vererbungsmechanismen. So konnen beispielsweise die Nachtei-le der pseudo-klassenbasierten Vererbung durch den Quelltext aus Listing 10 abge-schwacht werden [28, 19, S. 69-72, 18, S. 100-103].

    Listing 10: Prototypenbasierte Vererbung

    1 function Mammal (name) {2 this.name = name;3 }45 function Elephant(name) {6 Mammal.call(this , name);7 this.numberOfTusks = 2;8 }910 Elephant.prototype = Object.create(Mammal.prototype);11 Elephant.prototype.makeNoise = function () {12 console.log(this.name + " says: Tooeroooe!");13 }14

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 18

    15 var clyde = new Elephant("Clyde");16 clyde.name === "Clyde"; // true17 clyde.numberOfTusks === 2; // true18 clyde.makeNoise (); // "Clyde says: Tooeroooe !");

    Die beiden wesentlichen Unterschiede zur pseudo-klassenbasierten Version werden inZeile 10 ersichtlich, da dort der Konstruktoraufruf von Mammal durch einen Aufruf vonObject.create(Mammal.prototype) ersetzt wurde. Dies bringt den Vorteil, dass diebereits erwahnte Vermischung zwischen Instanzobjekten und Klassenobjekten aufgelostwird, so dass zwei sauber voneinander getrennte Hierarchien gepflegt werden konnen.Zudem erfolgt kein unnotiger Aufruf des Konstruktors Mammal, der zu unvorherseh-baren Programmabsturzen oder Nebeneekte fuhren kann. An dieser Stelle sei nochauf die Zeile 6 hingewiesen, die auch so im Beispiel der pseudo-klassenbasierten Ver-sion hatte auftauchen konnen. Es handelt sich dabei um einen indirekten Aufruf desKonstruktors Mammal, bei dem der Inhalt des ersten Arguments an die lokale Variablethis innerhalb des Konstruktors gebunden wird. In diesem Fall heit das ubergebeneArgument ebenfalls this, da es ja das Objekt reprasentiert, das durch den Aufruf newElephant() erzeugt wurde, und entsprechend initialisiert werden soll.

    3.5.4 Mixins als Alternative

    Der Vollstandigkeit halber soll hier noch eine Alternative zur Vererbung gezeigt werden,die ohne Prototypen arbeitet. Diese Alternative stellen die sog. Mixins dar, die kurzam Quelltextbeispiel 11 nachvollzogen werden sollen [19, S. 84 f.].

    Listing 11: Beispiel fur die Implementierung eines Mixins

    1 function mixin(receiver , supplier) {2 for (var property in supplier) {3 if (supplier.hasOwnProperty(property)) {4 receiver[property] = supplier[property]5 }6 }7 return receiver;8 }

    Das Schlusselwort in in der zweiten Zeile von Listing 11 ermoglicht den iterativenZugri auf alle Eigenschaften eines Objektes. Mit hasOwnProperty() kann gepruftwerden, ob die Eigenschaft eines Objektes von diesem Objekt selbst stammt oder mit-tels Delegation von einem Prototypen abgeleitet wurde. Handelt es sich um eine eigeneEigenschaft, so wird diese an den Empfanger (receiver) weitergegeben. Nach Been-den der Schleife verfugt der Empfanger uber alle Eigenschaften des Vorlage-Objektes(supplier). Mit dieser Methode ware es moglich mehrere Objekte miteinander zu ver-mischen und so eine Art von Mehrfachvererbung zu implementieren, wobei allerdingsschnell klar werden sollte, dass man spatestens bei Eigenschaften mit gleichem Namenvor einem Problem stunde.

    4 JavaScript in der Praxis

    Nachdem im vorherigen Kapitel JavaScript und dessen Prototypen vorgestellt wurden,befasst sich dieser Teil der Arbeit mit der professionellen Nutzung von JavaScript in

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 19

    der Praxis. Der Schwerpunkt liegt hierbei auf der Untersuchung der weit verbreitetenBibliothek jQuery. Nach einer kurzen Vorstellung der Software und ihres Funktions-umfangs, erfolgt im letzten Teil des Kapitels eine genauere Betrachtung von relevantenQuelltextausschnitten.

    4.1 Das jQuery-Projekt

    Wichtigstes Merkmal der Implementierung von JavaScript in Browsern ist die sog. Do-cument Object Model-API, die bereits 1998 durch das World Wide Web Consortium(W3C) standardisiert wurde und einen einheitlichen Zugri auf die Elemente einesHTML-Dokumentes ermoglicht. Diese Schnittstelle benennt diverse Funktionen, mitdenen die hierarchisch angeordneten Elemente einer XML-Struktur modifiziert unddurchlaufen werden konnen [29].In der Vergangenheit implementierten Browserhersteller diese Schnittstelle in ihrenProdukten und erweiterten sie haufig um eigene Funktionen, die mit der Zeit haufigselbst in den Standard gelangten. Leider wiesen viele Browser Eigenheiten bei der Im-plementierung auf, die von den Nutzern haufig durch Zwischenlosungen (z.B. der bereitsvorgestellte Polyfill) kompensiert werden mussten. Die Folge war, dass im Laufe derZeit Bibliotheken entstanden, die diese einzelnen Browserinkompatibilitaten kapseltenund haufig uber weitere, eigene Funktionen verfugten.Eine dieser Erweiterungen, die von vielen Entwicklern begrut wurde, war es CSS-Selektoren zur Auswahl von Elementen des DOMs zu nutzen, und so die unflexiblenFunktionen des W3C-Standards zu verbessern. Cascading Stylesheets boten bereits inder Version 1 im Jahr 1996 eine vielseitige Moglichkeiten auf die einzelnen Elemen-te eine HTML/XML-Dokuments zuzugreifen. Wahrend der Standard des W3C nureinen Zugri auf DOM-Elemente uber ihren Typ oder das Attribut ID vorsieht, un-terstutzten CSS-Selektoren weitere Zugrismoglichkeiten uber Klassen, Pseudoklassenund Pseudoelemente [30]. Daruber hinaus ist die die Verwendung der Selektoren vielenEntwicklern gut bekannt.Der Entwickler John Resig war ebenfalls von dieser Idee uberzeugt, bemangelte al-lerdings ihre Ausfuhrung in Form der damals verwendeten Bibliotheken (z.B. beha-viour.js). Resig entwicklelte daraufhin seine eigene Bibliothek namens jQuery, die imAugust 2005 veroentlich wurde und bis heute aktiv gepflegt und genutzt wird. Kern-bestandteil der Bibliothek war der von ihm entwickelte Code zur Nutzung von CSS-Selektoren in JavaScript, um einzelne Element oder Gruppen von Elementen selektierenzu konnen [31].13 Wie ezient diese Mechanik im Vergleich zu herkommlichen Java-Script ist, zeigt Listing 12.

    Listing 12: Vergleich JavaScript vs. jQuery

    1 // jQuery2 $.post('www.example.com/login ', { username: 'fred' }, function (

    data) {3 // Verarbeitung4 })56 // JavaScript

    13Dieser Kern heit heute Sizzle.js und wird als selbststandiges Projekt unter http://sizzlejs.com/weitergepflegt.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 20

    7 var httpRequest = new XMLHttpRequest ()8 httpRequest.onreadystatechange = function (data) {9 // Verarbeitung10 }11 httpRequest.setRequestHeader('Content-Type ', 'application/

    x-www-form-urlencoded ')12 httpRequest.open('POST', 'www.example.com/login ')13 httpRequest.send('username= ' + encodeURIComponent('fred'))

    Listing 12 zeigt einen asynchronen Serveraufruf mittels der POST-Methode des HTTP-Protokolls. Die Zeilen 2-4 zeigen die Implementierung mittels jQuery, die ubrigen Zeilendie klassische Variante mit JavaScript. Der reduzierte Aufwand fur den Programmiererwird durch den Umfang der beiden Beispiele deutlich.

    JQuery hat sich im Laufe der Jahre zu einem De-facto-Standard entwickelt. VieleQuelltext-Ausschnitte in Fachbuchern und auf Internetportalen nutzen die jQuery-Notation ohne explizit darauf hinzuweisen. Deutlich wird die hohe Verbreitung, wennman sich in Abbildung 8 die Nutzung und Marktanteile der Bibliothek im Vergleich zurKonkurrenz anschaut. Von den beobachteten Internetseiten, die http://www.w3techs.com in regelmaigen Abstanden untersucht, nutzen 35,1% uberhaupt keine Bibliothe-ken. 61,3% der beobachteten Seiten nutzen jQuery, was einem Marktanteil von 93,4%entspricht.14

    Die Webseite http://www.builtwith.com benennt fur den November 2014 49,4 Mio.Internetauftritte, die Verwendung von der Software machen. Abgeschlagen auf demzweiten Platz befindet sich der Konkurrent MooTools mit 3,6 Mio. Installationen. Die-sen starken Erfolg verdankt jQuery nicht nur der Selektor-Mechanik, sondern aucheiner Menge von weiteren Funktionen, um die das Projekt im Laufe der Jahre erwei-tert wurde [32, 33]. Die wichtigsten Funktionen lauten:

    DOM-Manipulation: Der wichtigste Einsatzzweck ist die bereits beschriebe-ne Veranderung des Document Object Model innerhalb eines Webbrowsers. Be-reits existierende DOM-Elemente konnen mittels CSS-Selektoren ausgewahlt undverandert werden. Neue Elemente konnen bequem erzeugt und in die existierendeHierarchie eingefugt werden.

    Ereignisbehandlung: Als clientseitige Technologie nutzt JavaScript ausgiebigTechniken der Ereignisbehandlung. Die jQuery-Bibliothek unterstutzt den Ent-wickler mit einer Vielzahl von browserunabhangigen Ereignisfunktionen, die aufDOM-Elemente angewendet werden konnen. Dabei bietet jQuery sogar die Mog-lichkeit auf Ereignisse zukunftiger Elemente, also Teilen des Dokuments, die nach-traglich dynamisch hinzugefugt wurden, zu reagieren.

    Animationen und Eekte: Um Nutzer auf Anderungen innerhalb des Doku-mentes aufmerksam zu machen und ggf. uber Erfolg und Misserfolg einer Aktionzu informieren, wird eine Menge von Animationen und Eekten angeboten.15

    AJAX: AJAX steht fur Asynchronous JavaScript and XML und beschreibt ei-ne Technik basierend auf dem XMLHttpRequest-Objekt, einer Funktionalitat

    14Es ist zu beachten, dass Webseiten auch haufig mehrere Bibliotheken gleichzeitig nutzen.15Das Projekt jQueryUI auf http://jqueryui.com/ erweitert diese Funktionalitat noch einmal deutlich.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 21

    Abbildung 8: Verbreitung verschiedener JavaScriptBibliotheken [Stand 15.12.2014], Quelle: w3techs.com

    des Browsers, die asynchrone HTTP-Anfragen an einen Server ermoglicht. Mo-derne Webanwendungen, die in Aufbau und Funktion an klassische Desktop-Applikationen erinnern (sog. Single Page Applications), waren ohne AJAX nichtmoglich. Detaillierte Informationen zum Thema AJAX konnen [34, Kap. 18] ent-nommen werden. JQuery bietet mit seinem ajax-Objekt eine vielseitig nutzbareSchnittstelle zur Verwendung von AJAX innerhalb diverser Laufzeitumgebungen.Ein Beispiel fur einen solchen AJAX-Aufruf wurde bereits mit der Methode postun Zeile 2 von Listing 12 gebracht.

    Fur den Entwickler ergeben sich aus der Nutzung von jQuery einige Vorteile [35, S.105 .]:

    Weniger Quelltext:Write less, do more lautet das Motto von jQuery. Das

    gezeigte Quelltextbeispiel (Listing 12) sollte vermittelt haben, dass jQuery diesdurchaus gelingt.

    Erhohte Lesbarkeit: Die Tatsache, dass durch geschickte Nutzung von Ereig-nismethoden samtlicher Quelltext in JavaScript vom eigentlichen XML/HTMLgetrennt werden kann (sog. unobtrusive JavaScript), erhoht zusammen mit denkurzen Quelltexten die Lesbarkeit.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 22

    Browserkompatibilitat: Die Gewahrleistung der Browserkompatibilitat wur-de nun bereits mehrfach erwahnt. JQuery unterstutzt sieben gangige Browser,darunter zwei mobile Anwendungen.

    Einfach zu erlernen: Durch die einfache Syntax, die Verwendung von CSS-Selektoren und gut dokumentierten Funktionen, die mit wenig Aufwand vieleAnderungen gleichzeitig am DOM zulassen, ist jQuery leicht zu erlernen.

    Groe Community: Mit der bereits besprochenen hohen Verbreitung geht aucheine sehr groe Entwicklergemeinschaft einher.

    Kostenlos: Die Bibliothek ist kostenlos und kann auf der Projektwebseite her-untergeladen werden oder uber ein sog. Content Delivery Network (CDN) in daseigene Projekt integriert werden.

    Erweiterbarkeit: JQuery bietet Erweiterungsmoglichkeiten, mit denen das Pro-jekt um zusatzliche Funktionen erganzt werden kann. Wie die Erweiterung derBibliothek technisch realisiert wird, ist unter anderem Inhalt des nachsten Ab-schnitts.

    Demgegenuber steht eine geringe Anzahl von Nachteilen:

    Dateigroe: Die Bibliothek ist durch den hohen Funktionsumfang mit einerDateigroe von 86 KByte sehr gro. Dies kann vor allem im mobilen Bereich zulangen Ladezeiten fuhren.

    Verdrangung von JavaScript: Die hohe Verbreitung jQueries hat zur Folge,dass viele Entwickler kaum Kontakt mit den standardisierten Browser-APIs ha-ben und fur viele Einsatzfalle nur noch die Bibliotheksfunktionen nutzen. Prinzi-piell spricht nichts gegen ein solche Nutzung, solange der Entwickler uber Kennt-nisse der dahinter liegenden Sprache verfugt und nicht blind auf fremde Imple-mentierungen vertraut.

    4.2 Untersuchung ausgewahlter Quelltextpassagen

    Der Erfolg der jQuery-Bibliothek hangt unter anderem stark von seiner einfachen Ver-wendung und der bereits erwahnten Erweiterbarkeit ab. Diese beiden Erfolgsfaktorenwaren ohne die eektive Nutzung JavaScripts funktionaler und prototypenbasierterSpracheigenschaften sicherlich nicht moglich gewesen. An ausgewahlten Teilen des Pro-jektquelltextes 16 soll diese Aussage belegt werden.

    4.2.1 Initialisierung des jQuery-Objekts

    Kern der Implementierung von jQuery ist das sog. jQuery-Objekt. Es handelt sichdabei um ein JavaScript-Objekt, das alle Bibliotheksmethoden vereint. Bereits dasInitialisieren diese Objektes macht ausgiebig Gebrauch von JavaScripts funktionalenEigenschaften.

    16Stand 19.11.2014, Version 2.1.1

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 23

    Listing 13: Erstmalige Erzeugung des jQuery-Objektes

    1 (function( global , factory ) {2 // call factory3 }( typeof window !== "undefined" ? window : this , function( window ,

    noGlobal ) {4 // define factory5 }

    Es handelt sich bei dem Konstrukt in Listing 13 um eine sog. Immediately InvokedFunction Expression(IIFE), also um die Definition einer anonymen Funktion, die direktausgefuhrt wird. Die Bibliothek stellt so sicher, dass sie an der Stelle, an der sie in einProjekt eingebunden wird, auch ausgefuhrt wird. Die Parameter der Funktion sindzum einen das globale Objekt, das durch die Laufzeitumgebung bereitgestellt wird,und zum anderen eine anonyme Funktion, die fur die eigentliche Initialisierung desObjektes zustandig ist und vom Funktionsparameter als factory bezeichnet wird.Die Erzeugung eines jQuery-Objektes ist sehr simpel und wird in Listing 14 gezeigt.

    Listing 14: Erzeugung eines jQuery-Objektes

    1 $("a")

    In Listing 14 wird ein Objekt erzeugt, das alle Elemente des Typs a, also alle(!) An-kerpunkte innerhalb des Dokumentes referenziert. Es fallt auf, dass fur die Objekter-zeugung weder das Schlusselwort new noch eine explizite Benennung eines Prototypengenutzt wird.

    Listing 15: Initialisierung des jQuery-Objektes

    1 // Define a local copy of jQuery2 jQuery = function( selector , context ) {3 // The jQuery object is actually just the init constructor '

    enhanced '4 // Need init if jQuery is called (just allow error to be thrown

    if not included)5 return new jQuery.fn.init( selector , context );6 },7 ...8 init = jQuery.fn.init = function( selector , context ) {9 // initialization10 ...11 };1213 // Give the init function the jQuery prototype for later

    instantiation14 init.prototype = jQuery.fn;

    Dies wird erreicht, indem die Funktion jQuery selbst den Konstruktoraufruf tatigt undeine Funktion namens init auf dem Objekt jQuery.fn aufruft (Listing 15, Zeile 5).Die Funktion init konfiguriert, abhangig von den ubergebenen Parametern, das neuerzeugte Objekt und ist somit die wahre Konstruktorfunktion der Bibliothek. Dies er-klart auch die Zuweisung in der letzten Zeile des Listings 15. Da es sich bei init um deneigentlichen Konstruktor handelt, muss dieser Funktion auch der Prototyp zugewiesenwerden, mit dem die spatere [[Prototype]]-Eigenschaft des neuen jQuery-Objektesbelegt werden soll.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 24

    4.2.2 Verwendung von Prototypen

    Bei jQuery.fn handelt es sich lediglich um eine Referenz auf jQuery.prototype, umden Code ubersichtlicher und kleiner zu halten. Dieser Prototyp beinhaltet alle wich-tigen Funktionen der Bibliothek, die in der API des Projektes aufgelistet werden. DerGroteil der mehr als 10.000 Zeilen Quelltext beschreibt diese Funktionen und bindetsie an das Prototypen-Objekt. Die Bindung der Funktionalitat an jQuery.fn bietetzwei groe Vorteile:

    1. Der Mechanismus der Objekterzeugung bleibt performant und ressourcenscho-nend. Wird ein neues Objekt erstellt, so muss lediglich die Referenz auf denexistierenden Prototypen kopiert, und nicht jede der vielen Bibliotheksfunktio-nen neu erzeugt werden (siehe letzte Zeile in Listing 15).

    2. Die Erweiterung der Bibliothek gestaltet sich besonders einfach, da neue Funktio-nen oder Eigenschaften nur an den Prototypen angefugt werden mussen, wodurchalle bereits existierenden und zukunftigen Objekte um diese Merkmale erganztwerden.

    Da sich die Implementierung der Funktionalitat eigentlich im Prototypen-Objekt be-findet, macht jQuery ausgiebig vom Prinzip der Delegation Gebrauch. Wir betrachtendazu in Listing 16 die Funktion before, die es ermoglicht ein DOM-Element vor einemanderen einzufugen.

    Listing 16: Beispiel fur die Verwendung von Delegation in der jQuery Bibliothek

    1 before: function () {2 return this.domManip( arguments , function( elem ) {3 if ( this.parentNode ) {4 this.parentNode.insertBefore( elem , this );5 }6 });7 },

    Innerhalb der Funktion des Prototypen sieht man die Verwendung von this.parentNode,wobei this in diesem Fall den Aufrufer, also ein konkretes jQuery-Objekt, und nichtjQuery.fn selbst meint.

    4.2.3 Weitere Besonderheiten im Entwurf

    Bei naherer Betrachtung des Quelltextes fallen weitere Entwurfsentscheidungen auf,die teilweise ausgiebig Gebrauch von JavaScripts Sprachfeatures machen, und durchgeschickte Implementierungen die Nutzung der Bibliothek deutlich vereinfachen.

    Globale Referenz: Das jQuery-Objekt wird nach Initialisierung als globale Re-ferenz gespeichert. Dies hat den Vorteil, dass standig eine Referenz auf den Pro-totypen jQuery.fn existent und somit unerreichbar fur die Garbage Collectionbleibt. Zum anderen fiel die Wahl des globalen Variablennamens auf ein ein-faches Dollarzeichen ($)17, das zu der mehrfach vorgestellten und pragnantenKurzschreibweise zur Erzeugung von jQuery-Objekten fuhrt.

    17Siehe [36] fur gultige Identifizierer in JavaScript.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 25

    Callback-Funktionen: Ereignisse und ihre Behandlung spielen in JavaScriptim Allgemeinen und in jQuery im Speziellen eine wichtige Rolle, da durch dieVerwendung im Browser auf eine Vielzahl von Benutzer- und Netzwerkereignissereagiert werden muss. Hierbei kommt haufig die funktionale Programmierungzur Anwendung, da mit ihr Ereignisfunktionen als Parameter ubergeben, und beiAuftritt des Ereignisses an Ort und Stelle ausgefuhrt werden konnen.

    Wrapped Sets: Eine Entwurfsentscheidung, die die Verwendung der Biblio-theksfunktionen stark vereinfacht, ist die der sog. Wrapped Sets. Ein jQuery-Objekt, das mit einem Selektor initialisiert wird, durchsucht das Dokument nachElementen, die diesem Selektor entsprechen. Das Ergebnis des Suchvorgangs isteine beliebig groe Menge von jQuery-Objekten, auf die alle bekannten Biblio-theksfunktionen angewendet werden konnen, wodurch eine explizite Iterationuber die Ergebnismenge entfallt.

    Verkettung von Funktionsaufrufen: Die Funktionen des jQuery-Objektes ge-ben haufig das Objekt selbst zuruck, und ermoglichen so eine einfache Verkettungvon Bibliotheksfunktionen.

    4.2.4 Praxisbeispiel

    Die aufgezahlten Besonderheiten sollen abschlieend in Listing 17 an einem eigenenQuelltextbeispiel erlautert werden.

    Listing 17: Verwendung von jQuery zur DOM-Manipulation

    1 2 3 4 5 $(function () {6 $("li").click(function () {7 $(this).css('color ', 'red').fadeOut('slow');8 });9 });10 11 12 13 14 Clyde 15 Fred 16 Bonny 17 18 19

    Listing 17 zeigt eine HTML-Seite mit einer ungeordneten Liste, die drei Eintrageenthalt. Der JavaScript-Quelltext startet in Zeile 5 mit dem sog. Document-Ready-Event, einer Callback-Funktion, die ausgelost wird, sobald der Browser das DOMvollstandig geladen hat.In Zeile 6 wird zunachst nun ein neues jQuery-Objekt mit dem Selektor

    li, also ein

    WrappedSet aus jQuery-Objekten, die uber das HTML-Tag li verfugen, erzeugt. Jedem

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 26

    dieser Elemente wird nun ein neuer Event-Listener zugewiesen, wobei die Zuweisungimplizit fur alle Elemente erfolgt (Zeile 6). Wird ein Element vom Benutzer angeklickt,so wird die ubergebene Callback-Funktion aufgerufen, die bewirkt, dass die Farbe desElements auf rot geandert, und das Element daraufhin langsam ausgeblendet wird(Zeile 7). Der Aufruf dieser beiden Anderungen erfolgt verkettet in Zeile 7. Mit demAufruf $(this) zeigt Zeile 7 ebenfalls ein Beispiel fur die Konvertierung (Wrap) einesStandard-DOM-Objektes zu einem jQuery-Objekt.An diesem kurzen Beispiel sieht man, wie ezient sich die Arbeitet mit der Bibliothekgestaltet. Mit lediglich vier verstandlichen Zeilen Quelltext wurden drei DOM-Elementeoptisch verandert, animiert und um eine Ereignisbehandlung erganzt, nachdem gepruftwurde, ob sie bereits vom Browser korrekt geladen wurden.

    5 Zukunftige Entwicklung und Fazit

    Douglas Crockford bezeichnet JavaScript als die missverstandenste Programmierspra-che der Welt, denn vielen Entwicklern sind die funktionalen und prototypenbasiertenSpracheigenschaften unbekannt18, was sicherlich an der eingeschrankten Nutzung zurDOM-Manipulation im Browser und der klassenbasierten

    Herkunft der Programmie-

    rer liegt. Die Kapitel 3 und 4 dieser Arbeit sollten gezeigt haben, dass die Sprache mitihren Prototypen, dem machtigen Konzept der Delegation sowie Closures uber eineMenge von flexiblen Werkzeugen verfugt, mit der sich weitaus mehr als die Modifika-tion von Webseiten erzielen lasst.Mit der schlechten Namenswahl der Sprache, dem Konzept der Konstruktoren und derunklaren Verwendung des Klassenbegris durch viele Autoren wurden im Verlauf derArbeit einige Makel JavaScripts in Bezug auf Prototypen aufgezeigt.Ein Blick auf die neuesten Entwicklungen des Sprachstandards und aktuelle Pra-xisbucher (z.B. [18, 19, 20]) zeigt, dass der Verwendung von prototypenbasierter Pro-grammierung in JavaScript in den letzten Jahren erhohte Aufmerksamkeit gebotenwurde. Standardisierte Funkionen wie Object.create oder Object.isPrototypeOfbrachten ernsthafte Alternativen zu den klassischen Entwurfsmustern JavaScripts, diesich vorwiegend auf die Nachahmung der klassenbasierten Programmierung konzen-trierten.Die ECMAScript Version 6, die sich noch im Entwurfsstadium befindet19, erweitertsowohl die konstruktor- als auch die prototypenbasierten Merkmale der Sprache umneue Funktionalitaten. Mit der Einfuhrung des Schlusselwortes class wird ein Wrap-per fur die pseudoklassenbasierte Vererbung, wie sie in Kapitel 3.5.1 beschrieben wurde,eingefuhrt.20 Die direkte Belegung von [[Prototype]] innerhalb von Objektliteralen,sowie die Moglichkeit, das Prototypenobjekt dynamisch zu andern, erhohen nochmalsdie Flexibilitat der Sprache.In Kapitel 4 wurde anhand praktischer Beispiele gezeigt, wie jQuery JavaScripts Sprachei-genschaften einsetzt, um eine performante, robuste und leicht verwendbare Nutzungseiner Bibliotheksfunktionen zu ermoglichen.Die Vielseitigkeit der Sprache wird noch deutlicher, wenn man sich aus JavaScripts

    18Vor Anfertigung dieser Arbeit zahlte sich der Autor ebenfalls dazu.19Stand: 02.12.201420Die Benennung des Schlusselwortes selbst empfindet der Autor als sehr zweifelhaft.

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 27

    Hauptdomane, dem Browser, entfernt, denn durch die flexible Paarung aus funktio-naler und prototypenbasiert Entwicklung hat die Sprache ihren Weg in diverse ande-re Einsatzgebiete gefunden. Mit node.js21 existiert seit 2009 ein Framework, das dieserverseitige Implementierung von Webseiten mit JavaScript ermoglicht. Node.js bie-tet dabei den Vorteil client- und serverseitig die selbe Sprache zu nutzen, wobei derSchwerpunkt auf der Verwendung des Ereignismodels (non-blocking I/O) JavaScriptsliegt. Auerhalb des WWW dient die Sprache hauptsachlich als Alternative zu existie-renden Scriptsprachen und DSLs, so verwenden Applikationen wie beispielsweise derAdobe Acrobat Reader, die dokumentenbasierte Datenbank MongoDB oder die Spiel-Engine Unity allesamt JavaScript als Scriptsprache, und tragen zur Verbreitung derprototypenbasierten Programmierung bei.

    6 Anhang

    Abbildungsverzeichnis

    1 Schematische Darstellung eines Objektes mit n+1 Slots, Quelle: EigeneDarstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

    2 Schematische Darstellung der Delegation, Quelle: Eigene Darstellung . 53 Forwarding vs. Delegation, Quelle: http://bit.ly/1yGzr2y . . . . . . 54 Prototypen in JavaScript, Quelle: Eigene Darstellung . . . . . . . . . . 125 Delegation in JavaScript, Quelle: Eigene Darstellung . . . . . . . . . . . 136 Pseudo-klassenbasierte Vererbung, Quelle: Eigene Darstellung . . . . . 157 Prototypenbasierte Vererbung, Quelle: Eigene Darstellung . . . . . . . 178 Verbreitung verschiedener JavaScript Bibliotheken [Stand 15.12.2014],

    Quelle: w3techs.com . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

    Literatur

    [1] Antero Taivalsaari. Classes vs. prototypes - Some Philosophical and HistoricalObservations. In: Journal of Object-Oriented Programming (1996).

    [2] Stanford Encyclopedia of Philosophy. Plato. 2013. url: http://stanford.io/1pjfY82 (besucht am 18. 11. 2014).

    [3] Stanford Encyclopedia of Philosophy. Aristotle. 2011. url: http://stanford.io/11sN62m (besucht am 18. 11. 2014).

    [4] Ludwig Wittgenstein. Philosophische Untersuchungen. Frankfurt am Main: Suhr-kamp, 1971. isbn: 3-518-06514-9.

    [5] George Lako. Women, fire, and dangerous things : what categories reveal aboutthe mind. Chicago: University of Chicago Press, 1987. isbn: 0-226-46804-6.

    [6] Alan Borning. Classes versus Prototypes in Object-Oriented Languages. In:Proceedings of the ACM/IEEE Fall Joint Computer Conference. November 1986.1986, S. 3640. isbn: 0-8186-4743-4.

    21http://nodejs.org/

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 28

    [7] Gunther Blaschek. Object-Oriented Programming with Prototypes. 1994. isbn:978-3-642-78079-0.

    [8] Henry Lieberman. Using Prototypical Objects to Implement Shared Behaviorin Object-Oriented Systems. In: OOPSLA86, ACM SIGPLAN. Bd. 21. 1. Nov.1986.

    [9] Christophe Dony, Jacques Malenfant und Daniel Bardou. Classifying Prototype-based Programming Languages. In: Prototype-Based Object-Oriented Program-ming: Concepts, Languages and Applications. Hrsg. von James Noble, AnteroTaivalsaari und Ivan Moore. Springer, Feb. 1999. Kap. 2, S. 1745.

    [10] Randall B. Smith und David Ungar. Programming as an Experience: The Inspi-ration for Self. In: Proceedings ECOOP 95. Bd. 952. LNCS. Springer-Verlag,Aug. 1995, S. 303330.

    [11] Marvin L. Minsky. A Framework for Representing Knowledge. In: The Psy-chology of Computer Vision. New York: McGraw-Hill, 1975, S. 211277.

    [12] F. Steimann. Moderne Programmiertechniken und -methoden: Kurseinheiten 1 -7. FernUniversitat Hagen, 2012.

    [13] Gunther Blaschek. The Omega Language - Introduction. url: http://bit.ly/1voFkB4 (besucht am 28. 11. 2014).

    [14] Charles Severance. JavaScript: Designing a Language in 10 Days. In: IEEEComputer 45.2 (2012), S. 78.

    [15] David Flanagan und Dan Shafer. JavaScript: The Definitive Guide. OReilly &Associates, 1998, S. 776. isbn: 1-56592-392-8.

    [16] ECMA. Standard ECMA 262, ECMAScript Language Specification. url: http://bit.ly/1vpiqe4 (besucht am 27. 11. 2014).

    [17] Douglas Crockford. JavaScript: The Worlds Most Misunderstood ProgrammingLanguage. 2001. url: http://bit.ly/1vpivyk (besucht am 27. 11. 2014).

    [18] Kyle Simpson. By Kyle Simpson You Dont Know JS: this & Object Prototypes.OReilly Media, Aug. 2014.

    [19] Nicholas C. Zakas. The Principles of Object-Oriented JavaScript. 1. Aufl. NoStarch Press, Feb. 2014. isbn: 978-1-593-27540-2.

    [20] Douglas Crockford. JavaScript: The Good Parts. 1st. OReilly Media, Mai 2008.isbn: 978-0-596-51774-8.

    [21] ECMA. ECMA-404: The JSON Data Interchange Format. 1st. ECMA (EuropeanAssociation for Standardizing Information und Communication Systems), Okt.2013. url: http://bit.ly/1vRJ7u6 (besucht am 27. 11. 2014).

    [22] Mozilla Developer Network (MDN) - new operator. 2014. url: http://mzl.la/1xM2M9S (besucht am 27. 11. 2014).

    [23] David Herman. Eective JavaScript: 68 Specific Ways to Harness the Power ofJavaScript. 1. Aufl. Addison-Wesley Professional, Dez. 2012. isbn: 978-0-321-81218-6.

    [24] Mozilla Developer Network (MDN) - Object.prototype. proto . 2014. url: http://mzl.la/1zSTq1S (besucht am 27. 11. 2014).

  • Seminararbeit zum Kurs 1908 - Thema: JavaScript 29

    [25] Draft ECMA-262 6th Edition. 2014. url: http://mzl.la/1rTkdmK (besucht am02. 12. 2014).

    [26] Mozilla Developer Network (MDN) - Object.prototype. 2014. url: http://mzl.la/1oAlm1C (besucht am 27. 11. 2014).

    [27] Joost Diepenmaat. Constructors Considered Mildly Confusing. 2013. url: http://bit.ly/1lmComJ (besucht am 15. 11. 2014).

    [28] Mozilla Developer Network (MDN) - Introduction to Object-Oriented JavaScript.2014. url: http://mzl.la/J1gPG5 (besucht am 15. 11. 2014).

    [29] W3C. Document Object Model. 2005. url: http://www.w3.org/DOM/ (besuchtam 18. 11. 2014).

    [30] W3C. Cascading Style Sheets, level 1. 2008. url: http://www.w3.org/TR/REC-CSS1/ (besucht am 18. 11. 2014).

    [31] John Resig. Selectors in JavaScript. 2005. url: http://bit.ly/1voIe8X.

    [32] jQuery Foundation. jQuery API. 2014. url: http://api.jquery.com (besuchtam 18. 11. 2014).

    [33] jQuery Foundation. History. 2014. url: https://jquery.org/history/ (be-sucht am 18. 11. 2014).

    [34] Stefan Koch. JavaScript - Einfuhrung, Programmierung und Referenz. 6. Aufl.Koln: Dpunkt-Verlag, 2011. isbn: 978-3-898-64731-1.

    [35] David Sawyer McFarland. JavaScript & jQuery: The Missing Manual. 3. Aufl.OReilly Media, Okt. 2014. isbn: 978-1-491-94707-4.

    [36] ECMA. ECMAScript 5.1, Identifier Names and Identifiers. 2014. url: http://bit.ly/15MnkbU (besucht am 01. 12. 2014).