JavaScript für Enterprise-Entwickler - Oliver Ochs - ebook

JavaScript für Enterprise-Entwickler ebook

Oliver Ochs

0,0

Opis

Immer mehr Programmierer von Enterprise-Anwendungen interessieren sich für JavaScript. Sie wollen sich schnell darin einarbeiten, sind aber oft nicht mit den gängigen JavaScript-Büchern für Webentwickler zufrieden. Nach einem schnellen Überblick über die JavaScript-Kernkonzepte geht es in diesem Buch daher ohne Umschweife an die spannenden Themen, u.a.: funktionales, prototypisches und objektorientiertes Programmieren, Testen, Packaging, Entwurfsmuster, jQuery und node.js. Kenntnisse in der Webentwicklung sind erforderlich, Jave-EE-oder .NET-Erfahrung ist hilfreich.

Ebooka przeczytasz w aplikacjach Legimi na:

Androidzie
iOS
czytnikach certyfikowanych
przez Legimi
Windows
10
Windows
Phone

Liczba stron: 302

Odsłuch ebooka (TTS) dostepny w abonamencie „ebooki+audiobooki bez limitu” w aplikacjach Legimi na:

Androidzie
iOS
Oceny
0,0
0
0
0
0
0



JavaScript für Enterprise-Entwickler

Oliver Ochs ist bei der Management- und IT-Unternehmensberatung Holisticon AG in der Leitung des Geschäftsfelds Architektur tätig. Seine Arbeitsschwerpunkte sind Architekturberatung, Softwaredesign und Entwicklung verteilter Systeme sowie die Beratung in Webprojekten. Dabei geht es u. a. um Website-Performanceoptimierung, Web-Content-Mangement, Java, Java EE und JavaScript. Oliver Ochs absolvierte ein Studium zum Dipl.-Ing. Medien und Informationswesen (FH) an der Hochschule für Technik, Wirtschaft und Medien in Offenburg.

JavaScript fürEnterprise-Entwickler

Professionell programmierenim Browser und auf dem Server

Oliver Ochs

Oliver [email protected]@holisticon.de

Lektorat: Réne Schönfeldt · Gabriel NeumannCopy-Editing: Ursula Zimpfer, HerrenbergHerstellung: Birgit BäuerleinUmschlaggestaltung: Helmut Kraus, www.exclam.deDruck und Bindung: M.P. Media-Print Informationstechnologie GmbH, 33100 Paderborn

Bibliografische Information der Deutschen NationalbibliothekDie Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie;detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

ISBN:Buch 978-3-89864-728-1PDF 978-3-86491-126-2ePub 978-3-86491-127-9

1. Auflage 2012Copyright © 2012 dpunkt.verlag GmbHRingstraße 19 B69115 Heidelberg

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.

Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.

Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.

5 4 3 2 1 0

Für Yako

Vorwort

Nahezu jede große Website – egal, ob das Backend in Java, PHP, Ruby oder Python programmiert wurde – verwendet im Browser JavaScript als Sprache. Selbst die Konkurrenz zu JavaScript im Browser – Adobe Flash – wird in Action-Script, einem Dialekt von JavaScript, programmiert. Softwareartefakte, die in JavaScript erstellt wurden, nehmen einen immer größeren Raum im Entwickleralltag ein.

An wen richtet sich dieses Buch?

Der Leser dieses Buchs lernt JavaScript-Entwicklung als professionelle Softwareentwicklung kennen. Teils muss er als Backend-Entwickler JavaScript-Code überarbeiten, der z. B. von einer Webagentur erstellt wurde, teils muss er auch selbst JavaScript-Artefakte erzeugen oder ein ganzes Framework oder eine Library in JavaScript schreiben oder pflegen. Nach der Lektüre des Buchs beherrscht er die Grundlagen der Sprache im Webbrowser. Zudem ermöglicht das Wissen dieses Buchs, auch die Anwendungsmöglichkeiten von JavaScript auf dem Server einzuschätzen und zu bewerten.

Dieses Buch richtet sich daher in erster Linie an Enterprise-Enwickler (meist mit einem Java-EE-Hintergrund), die sich für JavaScript interessieren, sich schnell darin einarbeiten wollen, aber nicht mit den gängigen Büchern für Webentwickler zufrieden sind. Ziel des Buchs ist es, aus einem Backend-Entwickler einen Full-Stack-Entwickler zu machen, der JavaScript seinem Werkzeugkasten hinzugefügt hat.

Wer neu in der Programmierung ist und JavaScript als erste Programmiersprache erlernen möchte, dem empfehle ich Marijn Haverbekes »Eloquent JavaScript« (»Die Kunst der JavaScript-Programmierung«). Wer JavaScript bereits kennt, aber einen fundierten Überblick über den Kern der Sprache wünscht, der lese lieber Douglas Crockfords »JavaScript: The Good Parts: Working with the Shallow Grain of JavaScript«. Wer eine Referenz zu JavaScript sucht, der ist mit Stefan Kochs »JavaScript: Einführung, Programmierung und Referenz« oder mit David Flanagans »JavaScript. The Definitive Guide« besser beraten.

Wie ist das Buch aufgebaut?

Unbestritten hat JavaScript viele Schwächen. Trotzdem ist JavaScript auch die am meisten missverstandene Programmiersprache. Aus diesem Grund sollte man sich mit den Kernkonzepten von JavaScript – also mit dem, was als Core JavaScript bezeichnet wird – eingehend beschäftigen und sie gut verstehen – unabhängig davon, ob man mit JavaScript im Browser oder auf dem Server entwickeln möchte.

Die Sprachkonzepte von Core JavaScript, dem Sprachkern von JavaScript, werden in den ersten Kapiteln des Buchs knapp, aber möglichst vollständig behandelt. Neuerungen in ES5 (ECMAScript1 5th Edition) werden natürlich ebenfalls angesprochen. Dabei wird JavaScript sowohl als schwach typisierte, dynamische und funktionale als auch als objektorientierte Programmiersprache betrachtet. Da JavaScript im Kern keine klassenbasiert-objektorientierte Sprache wie Java, sondern eine prototypische Sprache wie Self ist, werden besonders die Unterschiede herausgestellt. Ein prototypisches Sprachkonzept ist so flexibel, dass es leicht möglich ist, objektorientierte Konzepte durch ein Framework selbst zu implementieren.

Nachdem die Grundlagen der Sprache behandelt wurden und dem Entwickler die unterschiedlichen Paradigmen der Sprache bekannt sind, wird die Verwendung von JavaScript dann sowohl auf dem Server als auch im Browser beschrieben. Dabei werden gängige Projekte wie Node.js auf dem Server und die Bibliothek jQuery im Browser verwendet.

JavaScript ist eine nur schwach typisierte Sprache. Es gibt keinen Compiler, der einen selbst vor technischem Unfug warnt. Gerade in größeren Projekten und bei der Erstellung von Frameworks ist daher eine testgetriebene Entwicklung wichtig und eine möglichst große Testabdeckung wünschenswert. Darum wird testgetriebene Entwicklung in JavaScript beschrieben. Abgerundet wird das Buch durch einen Ausflug in die Build-Automatisierung und einen umfangeichen Anhang.

Codebeispiele sind in der Regel möglichst kurz gehalten. Der Leser benötigt also keine Entwicklungsumgebung, um sie nachzuvollziehen. Daher eignet sich dieses Buch auch als U-Bahn-Lektüre.

Wie liest man dieses Buch?

Dieses Buch kann von vorne bis hinten, aber auch selektiv gelesen werden. Wer einen Workshop erwartet, der sollte das Buch komplett lesen und versuchen, die Beispiele nachzuvollziehen. Wer allerdings nur einige Bereiche kennenlernen oder sein Wissen in Teilgebieten vertiefen möchte, dem werden nun die einzelnen Kapitel vorgestellt:

Kapitel 1 – Die Geschichte von JavaScript

Zum Verständnis der Sprache und der unterschiedlichen Laufzeitumgebungen ist es hilfreich, zumindest einen kurzen Überblick über die Entwicklung der Sprache zu kennen – von den Anfängen bei Netscape und den Browserkriegen über das Web 2.0 bis hin zu modernen Anwendungen im und außerhalb des Browsers.

Kapitel 2 – JavaScript-Laufzeitumgebungen

JavaScript benötigt eine Laufzeitumgebung, in der es ausgeführt wird. Die am häufigsten verwendete Laufzeitumgebung ist sicherlich der Webbrowser. Aber JavaScript lässt sich auch »headless«, d. h. außerhalb des Browsers, ausführen. Um die Beispiele der folgenden Kapitel möglichst effektiv (d. h. ohne einen Browser oder eine IDE) nachvollziehen zu können, werden verschiedene Laufzeitumgebungen aufgesetzt, um in diesen Umgebungen mit der Sprache zu experimentieren.

Kapitel 3 – Core-JavaScript

JavaScript ähnelt im Kern gängigen Sprachen wie C oder Java. Allerdings gibt es auch Unterschiede zu diesen Sprachen. Daher werden in diesem Kapitel die wichtigsten Kernfeatures der Sprache vorgestellt: von Anweisungen und Operatoren über Kontrollstrukturen bis hin zu Werten und Literalen. Jeder, der sich für die Sprache interessiert, sollte dieses Kapitel lesen, denn die Sprache birgt doch einige Überraschungen in sich.

Kapitel 4 – JavaScript als funktionale Programmiersprache

JavaScript ist eine Multi-Paradigmen-Sprache. Unterschiedliche Konzepte der funktionalen Programmierung, der prototypischen Programmierung und der objektorientierten Programmierung lassen sich in JavaScript mischen. In diesem Kapitel wird auf die funktionalen Aspekte von JavaScript eingegangen. Neben den Funktionen an sich werden auch Entwurfsmuster beschrieben, die in einer funktionalen JavaScript-Entwicklung Anwendung finden. Dieses Kapitel ist vor allem für Entwickler interessant, die bisher nur wenig in JavaScript programmiert haben. Zudem ist es Grundlage für die folgenden Kapitel.

Kapitel 5 – JavaScript als prototypische Programmiersprache

JavaScript ist durchaus eine objektorientierte Programmiersprache. Prototypisch bezeichnet die Art von Objektorientierung, die JavaScript verwendet. Allerdings kennt JavaScript keine Klassen, sondern lediglich Objekte und deren Prototypen. In diesem Kapitel wird beschrieben, wie sich Objekte erzeugen und verändern lassen. Dieses Kapitel ist Pflichtlektüre für alle Entwickler, die in einer klassischobjektorientierten Sprache zu Hause sind, denn die Unterschiede von JavaScript zu verbreiteten Sprachen wie Java sind doch zu groß, um sie ignorieren zu können.

Kapitel 6 – JavaScript als objektorientierte Programmiersprache

Obwohl das prototypische Paradigma von JavaScript ein sehr mächtiges Paradigma ist, fühlen sich Entwickler, die aus einer klassisch-objektorientierten Sprache kommen, mit einer prototypischen Sprache oft unwohl. Über verschiedene Entwurfsmuster zur Objekterzeugung wird eine eigene klassenbasierte Vererbung realisert. Diese eigene Implementierung wird gängigen Implementierungen gegenübergestellt. Sowohl die eigene als auch gängige Implementierungen fühlen sich in JavaScript jedoch wie ein Fremdkörper an. Daher werden die prototypische Vererbung und daraus resultierende Entwurfsmuster vorgestellt. ECMAScript 5th Edition ist die aktuelle Version von JavaScript. Sie wird in vielen Browsern zwar noch nicht verwendet, bietet aber viele neue Features, um mit Objekten zu arbeiten. Diese neuen Features werden kurz vorgestellt, auch wenn sich diese nur in Ausnahmefällen (wie auf dem Server) nutzen lassen. Dieses Kapitel ist für Entwickler interessant, die sich nicht nur für die praktische Anwendung, sondern auch für Sprachkonzepte interessieren.

Kapitel 7 – Eingebaute Objekte

Viel wurde bisher über Objekte und deren Erzeugung geschrieben. JavaScript hat selbst auch ein paar eigene Objekte – die API der Sprache: Dies sind Boolean, Number, String, Array, Object, Function, RegExp, Date und einige Objekte zur Fehlerbehandlung. Dieses Kapitel sollten Sie zumindest überfliegen, um sich einen Eindruck von den wenigen Objekten, die JavaScript mitbringt, zu verschaffen. Es gibt nur wenige Sprachen, deren API ein Entwickler komplett beherrschen kann. Daher lohnt es sich, dieses Kapitel nicht nur zu überfliegen, sondern auch zusammen mit dem Anhang komplett zu lesen, um sich ein Wissen über JavaScript möglichst vollständig anzulegen.

Kapitel 8 – Entwurfsmuster

Gängige Entwurfsmuster kommen aus klassenbasierten2 Sprachen wie C++ oder Java. Dieses Kapitel zeigt, wie sich diese Entwurfsmuster auch in JavaScript sinnvoll anwenden lassen. Neben klassischen Entwurfsmustern der sogenannten Gang of Four (GoF3) werden auch Entwurfsmuster vorgestellt, die in JavaScript häufiger als klassische GoF-Patterns anzutreffen sind. Entwurfsmuster sind bei Enterprise-Entwicklern sehr beliebt, darum darf dieses Kapitel in keinem Buch für Enterprise-Entwickler fehlen. Wer sein bisheriges Wissen über Entwurfsmuster auf JavaScript übertragen möchte, dem sei dieses Kapitel ans Herz gelegt.

Kapitel 9 – JavaScript im Webbrowser – Teil 1

Zwar ist dies kein klassisches Buch über Webentwicklung, doch darf ein Kapitel über den Webbrowser in keinem JavaScript-Buch fehlen. Der Browser ist die Laufzeitumgebung, für die JavaScript entwickelt wurde. Der meiste Code, der in JavaScript geschrieben wurde und wohl auch in Zukunft geschrieben wird, ist Code, der im Webbrowser läuft. In diesem Kapitel werden daher die wichtigsten Grundlagen vermittelt, die ein Entwickler über JavaScript im Browser wissen muss. Für Entwickler, die bereits die Grundlagen der Webentwicklung kennen, ist dieses Kapitel ein Repetitorium. Für Entwickler, die bisher im Backend unterwegs waren, ist dieses Kapitel aber sicher ein Pflichtkapitel.

Kapitel 10 – JavaScript auf dem Server mit Node

JavaScript wird in der Regel im Browser verwendet. Allerdings erlebt es zurzeit auch auf dem Server eine Renaissance. Als serverseitige Umgebung wird Node und das Framework »Express« vorgestellt. Dabei wird auch auf Modularisierung und Packaging eingegangen, denn Node motiviert das Verwenden von CommonJS-Modulen. Zwar werden die meisten Enterprise-Entwicklern in ihrem beruflichen Umfeld nur selten mit Node in Berührung kommen, doch ist dieses Kapitel trotzdem interessant, denn die Besonderheiten der Entwicklung mit JavaScript werden hier auf den Server übertragen. Für einen Full-Stack-Entwickler, der sowohl im Frontend als auch im Backend unterwegs ist, klingt es verführerisch, nur noch in einer einzigen Sprache zu entwickeln: JavaScript. Dies klingt umso verlockender, wenn der Trend von Thin Clients und intelligenten Servern hin zu Smart Clients und Thin Servern sich fortsetzen sollte. Eine Investition in Wissen um JavaScript auf dem Server ist also eine Investition in die Zukunft, eine Wette auf zukünftige Paradigmen der modernen Webentwicklung.

Kapitel 11 – JavaScript im Webbrowser – Teil 2

Nachdem eine erste serverseitige Anwendung erstellt wurde, steigt dieses Buch nun tiefer in die Webentwicklung im Webbrowser ein. Es werden die Grundlagen der Formularverarbeitung angesprochen und jQuery bzw. jQuery-UI werden kurz vorgestellt. Selbst wer das Kapitel über Node übersprungen hat, sollte an dieser Stelle wieder einsteigen. Die besprochenden Libraries werden zwar nicht tief gehend behandelt, allerdings sollte dieses Kapitel einen Überblick vermitteln.

Kapitel 12 – Build-Automatisierung

JavaScript ist keine kompilierende Sprache. Trotzdem macht Build-Automatisierung auch für JavaScript Sinn, denn Build-Automatisierung umfasst mehr als das Kompilieren von Quellcode in Binärcode, nämlich das Skripten von Tätigkeiten, die ein Entwickler während des Softwareentwicklungsprozesses täglich durchführt. Zu diesen Tätigkeiten, die sich leicht automatisieren lassen, gehört das Kompilieren des Quellcodes, das Paketieren (Packaging) des Codes bzw. des Binärcodes, das Durchführen von Unittests und Integrationstests, das Überprüfen von Coding-Conventions und anderen Qualitätsanforderungen, das Deployment auf Test- und Livesysteme und die Generierung von Dokumentationen und Release-Notes. Diese Tätigkeiten lassen sich auch über ein Shell-Skript automatisieren. Strukturierter lässt sich dies aber über ein Build-System erreichen. In diesem Kapitel werden zunächst die einzelnen Tätigkeiten beschrieben. Anschließend wird gezeigt, wie sich diese Tätigkeiten durch gängige Build-Systeme automatisieren lassen. Build-Automatisierung wird hier aus der Perspektive eines Enterprise-Java-Entwicklers beschrieben. Leser, die aus einem anderen Umfeld kommen, können sich durch dieses Kapitel inspirieren lassen, ähnliche Lösungen mit anderen Technologien zu realiseren.

Kapitel 13 – Testen

Da JavaScript-Anwendungen immer komplexer werden, kommt auch dem Testen eine immer größere Bedeutung zu. Gerade in größeren Projekten und bei der Erstellung von Frameworks ist eine testgetriebene Entwicklung wichtig und eine möglichst große Testabdeckung wünschenswert. Der Trend automatisierter Tests entwickelte sich dabei von der klassischen testgetriebenen Entwicklung (Test Driven Development, TDD) hin zum Behaviour Driven Development (BDD). Verteilte Tests in unterschiedlichen Webbrowsern lassen sich mit modernen Tools wie JsTestDriver automatisieren. Der Leser bekommt einen Überblick über das Testing in JavaScript. Da automatisierte Tests in keinem Werkzeugkasten fehlen sollten, ist dieses Kapitel eine Pflichtlektüre für professionelle Entwickler.

Referenz, Nachwort, Literaturliste und Index

Abgeschlossen wird das Buch von einer Referenz und einem Index zum Nachschlagen. Eine Literaturliste soll zum Weiterlesen anregen.

Danksagung

An dieser Stelle möchte ich zuerst meiner Frau Katharina und meinen Kindern Emma und Ada danken, dass sie mir die Zeit gaben, dieses Buch zu schreiben.

Außerdem möchte ich meinen Lektoren René Schönfeldt und Gabriel Neumann für ihre konstruktiven Vorschläge und allen Beteiligten im dpunkt.verlag danken. Ohne sie wäre dieses Buch nie entstanden. Ursula Zimpfer danke ich für ihre Korrekturen.

Ein großes Dankeschön geht auch an meine Korrekturleser Michael Gustav Simon, Enno Thieleke, Dr. Markus Liebelt und Sören Lünsdorf. Das Gleiche gilt für Benjamin Schmid, Golo Roden und meine anonymen Gutachter. Ihr teils sehr frühes Feedback war unbezahlbar!

Dieses Buch wäre auch ohne meine literarischen Vorbilder Stefan Koch, David Flanagan, Douglas Crockford, John Resig, Dustin Diaz, Stoyan Stefanov, Christian Johansen, Marjin Haverbeke und die zahllosen Mitwirkenden am Mozilla Developer Network nie entstanden.

Sollte ich jemanden vergessen haben oder es versäumt haben, einen Artikel, aus dem ich geschöpft habe, zu erwähnen, dann lassen Sie es mich wissen, sodass ich dies nachtragen kann.

Inhaltsverzeichnis

1         Die Geschichte von JavaScript

1.1      JavaScript – die Lingua franca des WWW

1.2      Netscape und JavaScript

1.3      Das Vorbild Self

1.4      Das Vorbild Scheme

1.5      JavaScript und ECMAScript

1.6      ECMAScript 5th Edition

1.7      Harmony

1.8      JavaScript und HTML5

1.9      New Wave JavaScript

1.10     Die JavaScript-Revolution

1.11     Zusammenfassung

2         JavaScript-Laufzeitumgebungen

2.1      JavaScript-Interpreter

2.2      Read-Eval-Print-Loop

2.3      Der Browser

2.4      Headless JavaScript

2.5      Rhino

2.6      SpiderMonkey, TraceMonkey und JägerMonkey

2.7      Google V8

2.8      SquirrelFish und Nitro, Microsoft und Opera

2.9      Welche Umgebung für welchen Zweck?

2.10     Entwicklungsumgebungen

2.11     Zusammenfassung

3         Core JavaScript

3.1      Skriptsprachen

3.2      Typen und Werte

3.2.1      Schwache Typisierung

3.2.2      Literale

3.2.3      Typeof-Operator

3.2.4      Typenlose Verwendung

3.3      Imperative Programmierung

3.3.1      Ausdrücke und Operatoren

3.3.2      Vergleiche

3.3.3      Variablen

3.3.4      Blöcke und Gültigkeit von Variablen

3.3.5      Zahlen

3.3.6      Zeichenketten

3.3.7      Boolesche Werte

3.3.8      Arrays

3.3.9      Reguläre Ausdrücke

3.3.10      Kommentare

3.3.11      Tokens und Whitespaces

3.3.12      Kontrollstrukturen

3.3.13      Schleifen

3.3.14      Ausnahmebehandlung

3.4      Objektliteral

3.5      Zusammenfassung

4         JavaScript als funktionale Programmiersprache

4.1      Funktionsliteral

4.2      Funktionsnamen

4.3      Parameter und Parametervalidierung

4.4      Konfigurationsobjekt als lesbarer Parameter

4.5      Anonyme Funktionen

4.6      Geltungsbereiche (Scopes)

4.7      this

4.8      Geschachtelte Scopes und der globale Namensraum

4.9      Closures und Module

4.10     Funktionale Vererbung

4.11     Callbacks

4.12     Kaskaden

4.13     Rekursion

4.14      Funktions-Caching

4.15     Currying

4.16     Zusammenfassung

5         JavaScript als prototypische Programmiersprache

5.1      Definition und Verwendung

5.2      Duck-Typing

5.3      Prototypen

5.4      Konstruktoren

5.4.1      Kontruktoren und die new-Anweisung

5.4.2      Entwurfsmuster für die new-Anweisung

5.4.3      Konstruktor- und Prototypreferenz

5.5      this

5.5.1      Globales Objekt

5.5.2      Funktion

5.5.3      Methode

5.5.4      Konstruktor

5.5.5      that

5.6      Reflexion

5.7      Löschen von Eigenschaften

5.8      Zusammenfassung

6         JavaScript als objektorientierte Programmiersprache

6.1      Objekterzeugungsmuster

6.1.1      Rent-a-Constructor

6.1.2      Konstruktoren überladen

6.1.3      Rent-a-Constructor-and-a-Prototype

6.1.4      Referenz auf die Superklasse halten

6.2      Existierende Bibliotheken

6.2.1      Klassenbasierte Vererbung in Prototype

6.2.2      Douglas Crockfords Classical Inheritance in JavaScript

6.2.3      John Resigs Simple JavaScript Inheritance

6.3      Prototypische Vererbung

6.4      Vererbung durch Kopieren

6.5      Mixins

6.6      Einzelne Methoden wiederverwenden

6.7      Objekte in ES5

6.7.1      Object.preventExtensions

6.7.2      Object.isExtensible

6.7.3      Object.seal

6.7.4      Object.isSealed

6.7.5      Object.freeze

6.7.6      Object.isFrozen

6.8      Objekteigenschaften in ES5

6.8.1      Accessor-Properties

6.8.2      Property-Descriptor

6.8.3      Object.defineProperty

6.8.4      Object.defineProperties

6.8.5      Object.getOwnPropertyDescriptor

6.8.6      Object.keys

6.8.7      Object.getOwnPropertyNames

6.8.8      Enumeration

6.9      Objekterzeugung in ES5

6.10     Bind in ES5

6.11     Zusammenfassung

7         Eingebaute Objekte

7.1      Boolean

7.2      Number

7.3      String

7.4      Array

7.4.1      Array-ähnliche Objekte

7.4.2      Arrays und reguläre Ausdrücke

7.4.3      Arrays und ECMAScript 5th Edition

7.5      Date

7.6      Math

7.7      RegExp

7.8      Zusammenfassung

8         Entwurfsmuster

8.1      Singleton

8.2      Iterator

8.3      Factory

8.4      Strategy

8.5      Decorator

8.6      Bridge

8.7      Facade

8.8      Adapter

8.9      Proxy

8.10     Mediator

8.11     Observer

8.12     Template-Method

8.13     Command

8.14     Spooling

8.15     Futures und Promises

8.16     Fear of Code

8.17     Zusammenfassung

9         JavaScript im Webbrowser – Teil 1

9.1      Sandboxing

9.2      Einbettung und Referenzierung

9.3      Das Laden der Seite

9.4      Das Window-Objekt

9.5      Das Document-Objekt

9.6      DOM-API

9.7      Timer

9.8      Events

9.9      Zusammenfassung

10       JavaScript auf dem Server mit Node

10.1     Node-Grundlagen

10.1.1     Netzwerkapplikationen

10.1.2     Non-Blocking I/O

10.1.3     Event-Loop

10.1.4     Anwendungsfälle für Node

10.2     Node installieren

10.3     Hello World in Node

10.4     Events

10.5     Buffer

10.6     Streams

10.6.1     Readable Streams

10.6.2     Writable Streams

10.7     Weitere APIs

10.8     Module

10.9      Package-Management

10.10   Debugging

10.11   Beispielapplikation mit dem Express-Framework

10.12   Zusammenfassung

11        JavaScript im Webbrowser – Teil 2

11.1     Formulare

11.2     Ajax

11.3     Eine Einführung in jQuery

11.4     Einführung in jQuery-UI

11.4.1     Widgets

11.4.2     Interaction-Helpers und Effekte

11.4.3     Themeroller

11.5     Zusammenfassung

12        Build-Automatisierung

12.1     Kompilieren

12.2     Packaging

12.2.1     Assemblierung

12.2.2     Minifizierung

12.2.3     CommonJS-Module und Pakete

12.3     Testing

12.4     Linting

12.5     Deployment

12.6     Dokumentation

12.7     Maven

12.7.1     wro4j

12.7.2     Jasmine-Maven-Plug-in

12.7.3     JsDoc-Toolkit-Maven-Plug-in

12.8     Weitere Build-Systeme

12.9     Require.js

12.10    Zusammenfassung

13        Testen

13.1     Klassisches Testen

13.2     User-Interface-Tests

13.3     Testgetriebene Entwicklung

13.4     Unit Tests

13.5     Modultests im Browser

13.6     Stand-alone-Unit-Tests mit Jasmine

13.7     Verteiltes Testen mit JsTestDriver

13.8     Zusammenfassung

14         Nachwort

Anhang

A        Referenz Core JavaScript

A.1      Anweisungen

A.1.1      Leere Anweisung

A.1.2      Var-Anweisung

A.1.3      Let-Anweisung

A.1.4      Const-Anweisung

A.1.5      Block-Anweisung

A.1.6      Try-Catch-Finally-Block

A.1.7      Throw-Anweisung

A.1.8      Debugger-Anweisung

A.1.9      Return-Anweisung

A.2      Ausdrücke und Operatoren

A.2.1      Ausdrücke

A.2.2      Operatoren

A.3      Kontrollstrukturen

A.3.1      If-Else-Anweisung

A.3.2      Switch-Case-Anweisung

A.3.3      While-Anweisung

A.3.4      Repeat-Until-Anweisung

A.3.5      Do-While-Anweisung

A.3.6      For-Anweisung

A.3.7      Label-Anweisung

A.3.8      Break-Anweisung

A.3.9      Continue-Anweisung

A.4      Whitespaces

A.5      Kommentare

A.6      Werte

A.7      Literale

A.7.1      Number

A.7.2      NaN

A.7.3      Infinity

A.7.4      Formatierung

A.7.5      number.toFixed

A.7.6      number.toPrecision

A.7.7      number.toString

A.7.8      number.toExponential

A.7.9      parseInt

A.7.10      parseFloat

A.8      Strings

A.9      Boolean

A.10     Reguläre Ausdrücke

A.11     Array

A.12     Objektliterale

B        Objektreferenz

B.1      Boolean

B.1.1      Konstruktor

B.1.2      Eigenschaften

B.1.3      Methoden

B.2      Number

B.2.1      Konstruktor

B.2.2      Eigenschaften

B.2.3      Methoden

B.3      String

B.3.1      Konstruktor

B.3.2      Eigenschaften

B.3.3      Methoden

B.4      Array

B.4.1      Konstruktor

B.4.2      Eigenschaften

B.4.3      Methoden

B.5      Date

B.5.1      Konstruktor

B.5.2      Methoden

B.6      Math

B.6.1      Konstruktor

B.6.2      Konstanten

B.6.3      Rundungsfunktionen

B.6.4      Filterfunktionen

B.6.5      Trigonometrische Funktionen

B.6.6      Logarithmische Funktionen

B.6.7      Sonstige Funktionen

B.7      RegExp

B.7.1      Konstruktor

B.7.2      Zeichen

B.7.3      Eigenschaften

B.7.4      Methoden

C         Namen und Namenskonventionen

D         JavaScript-Laufzeitumgebungen installieren

D.1      Rhino

D.2      TraceMonkey

D.3      Google V8

E         Literatur

           Index

1 Die Geschichte von JavaScript

Um JavaScript und seine verschiedenen Ausprägungen einordnen zu können, ist ein kurzer Blick in die Geschichte von JavaScript sinnvoll. Es wird zunächst berichtet, wie JavaScript entstanden ist und was die Vorbilder von JavaScript waren. Dies ist wichtig, um JavaScript von bekannten objektorientierten Programmiersprachen wie Java unterscheiden zu können. Dann werden die unterschiedlichen Ausprängungen und Implementierungen der Sprache angesprochen, um schließlich moderne Strömungen kurz anreißen zu können.

1.1 JavaScript – die Lingua franca des WWW

Nahezu jede Website – egal in welcher Sprache das Backend programmiert wurde – verwendet im Browser JavaScript als Programmiersprache. Selbst Adobe Flash wird in ActionScript, einem Dialekt von JavaScript, programmiert. Daher kommt fast jeder Webentwickler zwangsläufig mit JavaScript in Berührung. Dies macht JavaScript zu einer der am häufigsten verwendeten Programmiersprachen der Welt. Mit anderen Worten: JavaScript ist die Lingua franca des World Wide Web!

1.2 Netscape und JavaScript

1994 gründete Marc Andreessen, einer der Mitentwickler des NCSA1 Mosaic Web Browser, die Firma Netscape, die den ersten kommerziell erfolgreichen Webbrowser, den Netscape Navigator, veröffentlichte. Mit dem Netscape Navigator wurde das World Wide Web, wie wir es heute kennen, geboren. Allerdings konnte die erste Version des Netscape Navigator nur statische HTML-Seiten darstellen.

Brendan Eich, der zuvor u. a. bei Silicon Graphics gearbeitet hatte und heute der CTO der Mozilla Foundation ist, stieß 1995 zu Netscape. Dort entwickelte er die Skriptsprache Mocha, die dann in LiveScript umbenannt und schon im September 1995 mit dem Netscape Navigator 2.0 ausgeliefert wurde. Bereits im Dezember 1995 wurde LiveScript nochmals umbenannt, dieses Mal in JavaScript. Der Name JavaScript hat technisch nichts mit Java zu tun, einer Programmiersprache, die gerade von Sun Microsystems entwickelt wurde, sondern wurde aus Marketinggründen gewählt, um vom Hype um das gerade populär werdende Java zu profitieren.

Als Gegenleistung für die Namensrechte an Java lieferte Netscape die Java Virtual Machine von Sun Microsystems zusammen mit ihrem Netscape Navigator aus. Die Zusammenarbeit von Netscape und Sun Microsystems fand 1999 ihren Höhepunkt in der Sun | Netscape Alliance und der iPlanet-Produktfamilie.

Durch die Namensverwandtschaft mit Java und durch die C-ähnliche Syntax wird JavaScript meist als ein abgespecktes Java oder C verstanden, ohne die mächtigen Features, die es bietet, zu erahnen.

Böse Zungen behaupten, Eich hätte jeden Fehler, der je beim Design einer Programmiersprache begonnen wurde, aufgegriffen, ein paar mehr Fehler erfunden und daraus JavaScript entwickelt. Unbestritten hat JavaScript viele Schwächen. Trotzdem ist JavaScript auch die am meisten missverstandene Programmiersprache. Als JavaScript entwickelt wurde, waren die Vorbilder nämlich nicht nur C oder Java, sondern auch Self2 von Sun Microsystems und Scheme3.

1.3 Das Vorbild Self

Self wurde bereits in den 1980ern als Projekt bei Xerox PARC gestartet und später bei Sun Microsystems fortgeführt. Self sollte dem Programmierer noch mehr Freiheiten im objektorientierten Programmieren bieten als das damals sehr verbreitete Smalltalk. Um dies zu erreichen, wurde Self gegenüber Smalltalk vereinfacht. Das erste Paper zu Self trug darum auch den passenden Titel: »Self: The Power of Simplicity«4.

Self basiert auf wenigen, einfachen Konstrukten: Prototypen, Slots und Traits. In Self gibt es, im Gegensatz zu Smalltalk, weder Klassen noch Variablen. Es wird also nicht zwischen dem Verhalten eines Objekts (den Methoden einer Klasse) und dem Zustand des Objekts (den Variablen bzw. den Eigenschaften) unterschieden. Objekte bestehen aus Slots. Slots haben einen Namen und können entweder ein Attribut oder eine Methode aufnehmen. Neue Objekte werden nicht durch das Erzeugen (fälschlicherweise inzwischen auch Instanziieren genannt) von Klassen, sondern durch Kopieren eines anderen Objekts erzeugt. Das Quellobjekt wird als Prototyp, d. h. als Kopiervorlage für das neue Objekt, benutzt. Es wird dabei sowohl das Verhalten als auch der Zustand des Objekts kopiert. Die prototypische Vererbung in Self ist also eine Weiterentwicklung der klassenbasierten Vererbung aus Smalltalk.

1.4 Das Vorbild Scheme

Scheme ist ein Lisp-Dialekt. Scheme unterstützt neben der reinen funktionalen Programmierung auch Paradigmen, die dazu im Widerspruch stehen, wie die der imperativen Programmierung. Das Grundprinzip von Scheme ist es, eine Sprache nicht dadurch mächtig werden zu lassen, indem man immer mehr Features hinzufügt, sondern indem man Einschränkungen entfernt. So gibt es in Scheme keine Objekte oder andere Paradigmen der objektorientierten Programmierung. Allerdings kann man sich solche Hilfsmittel leicht selbst programmieren. Scheme ist also eine »programmierbare Programmiersprache«.5 In den Sourcecode-Reposi-tories der Mozilla Foundation lässt sich noch heute eine in Lisp implementierte JavaScript-Engine finden.6

1.5 JavaScript und ECMAScript

Nachdem der Netscape Navigator 2 in 1995 mit JavaScript ausgeliefert wurde, entwickelte Microsoft eine zu JavaScript weitestgehend kompatible Sprache, die JScript getauft und im August 1996 mit dem Internet Explorer 3.0 ausgeliefert wurde.

Um eine Fragmentierung der Sprache zu vermeiden, reichte Netscape im November 1996 JavaScript bei der ECMA – der European Computer Manufacturers Association – ein, damit diese eine standardisierte Version unter dem Namen ECMAScript entwickeln konnte.

ECMAScript 1st Edition wurde 1997 veröffentlicht. Implementiert wurde es von JavaScript 1.2 (Netscape 4.07) und JScript 3.0 (Internet Explorer 4.0).

ECMAScript 2nd Edition wurde ein Jahr später, 1998, veröffentlicht.

ECMAScript 3rd Edition (ES3), die dritte Ausgabe von ECMAScript, erschien bereits im Folgejahr 1999. Sowohl JavaScript 1.5 (Netscape 6, Mozilla) als auch JScript 5.5 (Internet Explorer 5.5) implementieren ECMAScript 3rd Edition. Im Browserbereich ist ECMAScript 3rd Edition also die Version, die von gängigen Browsern unterstützt wird. Sie ist im Moment der kleinste gemeinsame Nenner für JavaScript-Entwickler.

Nach ECMAScript 3rd Edition war es lange ruhig um die Standardisierung von JavaScript. Erst 2005 wurde die Erweiterung ECMAScript for XML (E4X) verabschiedet. Dieser Standard fügt XML als nativen Datentyp und Funktionen, um XML zu bearbeiten, zu JavaScript hinzu.7 Allerdings wird E4X nicht von allen aktuellen Laufzeitumgebungen komplett implementiert.

Die ECMA plante, mit ECMAScript 4th Edition JavaScript komplett zu überarbeiten. JavaScript sollte Interfaces, Klassen, klassenbasierte Vererbung und ein statisches Typsystem bekommen. Dies rief Widerstände hervor, da diese Veränderungen dem Ursprung und der Natur von JavaScript zuwiderliefen. Diese Widerstände zwangen die ECMA dazu, die Arbeit an ECMAScript 4th Edition im Oktober 2008 einzustellen.

ActionScript, die Programmiersprache von Adobe Flash, beruht ab der Version 3.0 auf Entwürfen zu ECMAScript 4th Edition. ActionScript 3 enthält z. B. statische Typisierung und klassenbasierte Objektorientierung. Da die Arbeit an ECMAScript 4th Edition eingestellt wurde, verfolgt Adobe also einen isolierten Weg in Sachen JavaScript. ActionScript ist also nicht das »bessere« oder »weiterentwickelte« JavaScript, sondern lediglich eine Abspaltung.

1.6 ECMAScript 5th Edition

Die aktuelle Ausgabe von ECMAScript ist die 5th Edition (ES5). Einige Teile von ECMAScript 5th Edition können heute bereits verwendet werden. Diese werden neben ECMAScript 3rd Edition auch in diesem Buch behandelt. Mit ECMA-Script 5.1 wurde ECMAScript 5th Edition aktualisiert.

Strict Mode

Der Strict Mode ist ein neues Feature von ECMAScript 5th Edition. Wenn der Strict Mode aktiviert ist, dann verhält sich JavaScript nicht mehr rückwärtskompatibel zu ECMAScript 3rd Edition, sondern folgt allein den Regeln von ECMAScript 5th Edition. Alle Features, die in ECMAScript 5th Edition als »deprecated« gekennzeichnet wurden, funktionieren dann nicht mehr. Man schaltet den Strict Mode ein, indem man im Kopf eines Programms und/oder einer Funktion einen leeren String “use strict“ definiert:

"use strict";

Den Strict Mode sollte man verwenden, wenn man eigene Bibliotheken erstellen möchte, die in einer kontrollierten Umgebung verwendet werden. Der Strict Mode macht die Entwicklung einfacher, denn der JavaScript-Interpreter muss sich nicht um Rückwärtskompatibilitäten kümmern, sondern muss nur noch der ECMAScript 5th Edition folgen. Zudem sind im Strict Mode für den Interpreter mehr Laufzeitoptimierungen als im Kompatibilitätsmodus möglich. Mehr zum Strict Mode findet man im Mozilla Developer Network.8

1.7 Harmony

ECMAScript wird im Moment unter dem Codenamen »Harmony« weiterentwickelt hin zu ECMAScript 6th Edition (ES6). In ES6 fließen viele Ideen ein, die ursprünglich in ECMAScript 4th Edition enthalten sein sollten.

1.8 JavaScript und HTML5

In HTML5 wird JavaScript scheinbar unabhängig von der ECMA weiterentwickelt. In HTML5 werden aber lediglich neue APIs im Browser definiert. Diese neuen APIs ermöglichen es nicht nur, reichhaltigere Websites mit generierten Grafiken, Multitasking sowie Multimedia ohne Plug-ins zu erstellen, sondern sie widmen sich vor allem auch mobilem Computing (z. B. auf dem Smartphone), indem sie Offline-Fähigkeit oder ein Geo-Locations-API definieren. Die Sprache JavaScript selbst betreffen diese Erweiterungen nicht.

1.9 New Wave JavaScript

Während des »Browserkriegs«9 (1995–1998) zwischen Netscape und Microsoft wurden zueinander inkompatible Versionen von JavaScript entwickelt, die der professionellen Nutzung der Sprache zuwiderliefen. Im Kern waren beide JavaScript-Implementierungen identisch. Um Dokumente im Webbrowser zu verändern, wurden allerdings unterschiedliche und verschieden mächtige APIs angeboten. Diese APIs, um Dokumente im Browser zu verändern, wurden zwar auch unter dem Namen DOM – Document Object Model – standardisiert, doch waren auch die DOM-Implementierungen nicht identisch. Diese Inkompatibilität schreckte professionelle Entwickler ab. Eine weitere Inkompatibilität ist die Ajax-API (Ajax steht für Asynchronous JavaScript and XML), die es ermöglicht, Requests aus einer Website abzusetzen, ohne die Website neu zu laden.

Erst mit dem Ende des Browserkriegs und dem Aufkommen von Web 2.0-Applikationen um 2004, die Inkompatibilitäten durch Bibliotheken kapselten, richtete sich das Augenmerk der Entwickler wieder auf JavaScript.

Die erste prominente Bibliothek war Prototype, das zusammen mit Ruby on Rails ausgeliefert wurde. John Resig schrieb die Bibliothek jQuery, da Prototype einige Schwächen aufwies. Daher sind sich Prototype und jQuery sehr ähnlich.

Prototype und jQuery bilden eine Abstraktionsschicht um das DOM und um Ajax-Funktionalitäten. Man verwendet nicht mehr die native API des Browsers, sondern nur noch die API, die Prototype oder jQuery bieten. Diese rufen dann je nach Browser die passenden Implementierungen auf, ohne dass sich der Entwickler um Browser-Inkompatibilitäten kümmern muss. Zusätzlich bieten sie grafische Effekte wie animiertes Ein- und Ausblenden von Elementen.

Weitere Bibliotheken wie YUI, jQuery-UI, Moo-Tools, SproutCore und ExtJS erlauben es, anspruchsvolle Anwendungen im Browser zu erstellen, die einer Desktop-Anwendung ähneln.

GWT und Cappuccino helfen dabei, Rich-Client-Anwendungen zu schreiben, die nicht nur so aussehen und sich bedienen lassen wie eine klassische Desktop-Anwendung, sondern auch genauso programmiert werden. Googles Web Toolkit GWT kompiliert in Java geschriebene Applikationslogik zu JavaScript, sodass Java-Entwickler Applikationslogik in Java formulieren bzw. bereits existierende Logik in JavaScript wiederverwenden können. Cappuccino versucht das Gleiche mit Objective-J und Cocoa. Objective-J ist eine an Apples Objective-C angelehnte Übermenge von JavaScript. Es erweitert JavaScript um klassenbasierte Vererbung und pseudostatische Typisierung. Cocoa ist eine objektorientierte API zur Programmierung unter dem Apple-Betriebssystem Mac OS X.

1.10 Die JavaScript-Revolution

In den letzten Jahren hat sich der Webbrowser zu der wichtigsten Anwendung auf dem Desktop-Rechner und im Smartphone entwickelt. Er ist in die Domäne von ausgewachsenen Applikationen wie Mail-Clients und Office-Suiten vorgestoßen und hat scheinbar allgegenwärtige Programme wie Microsoft Outlook und Word teilweise bereits verdrängt. Anwendungslogik wandert zunehmend vom Server zum Client, vom Backend in den Webbrowser, vom Thin Client in den Smart Client.

Wenn immer mehr Anwendungslogik vom Server in den Client verlagert wird, stellt sich für einen Entwickler die Frage, ob der Rest der Anwendungslogik im Thin Server nicht in der gleichen Sprache entwickelt werden kann, die auch im Webbrowser verwendet wird. Es gibt zudem keinen logischen Grund, warum JavaScript ausschließlich im Webbrowser laufen sollte. Und es erscheint wirtschaftlich, wenn man auf eine große Zahl an Entwicklern zurückgreifen kann, die in einer einzigen Sprache programmieren. JavaScript auf dem Server könnte sicherlich nicht gewachsene SAP- oder SOA-Umgebungen, dafür aber Webframeworks wie ASP.NET, Spring MVC/Webflow oder JSF ersetzen.

Inzwischen wird JavaScript also auf dem Server interessant. Sogar Datenbanken wie Couch-DB verwenden JavaScript als native Abfragesprache. Mit ECMA-Script 5th Edition gibt es zudem in der Sprache selbst interessante neue Features.

Auch auf dem Smartphone ist JavaScript eine Sprache, in der sich Apps entwickeln lassen – kleine Applikationen, die als native Anwendungen auf dem Telefon laufen.

JavaScript im Browser ist inzwischen wohldefiniert und stabil. Inkompatibilitäten der Browser werden durch Toolkits hinreichend gekapselt. Leider gibt es außerhalb des Browsers noch keine Standardbibliotheken, um Anwendungen zu schreiben. So ist in JavaScript der Zugriff auf lokale Dateien und Netzwerk-Sockets nicht definiert. Daher lassen sich diese Features auch nicht durch ein gewöhnliches Toolkit kapseln.

In Anlehnung an Common Lisp, die Standardbibliothek von Lisp, versucht CommonJS diese Lücke zu schließen. Ein Anwendungsentwickler soll eine JavaScript-Applikation, egal ob es eine Server-, Desktop- oder Kommandozeilenanwendung ist, in verschiedenen Laufzeitumgebungen laufen lassen können. Eine Implementierung von CommonJS ist node.js, in diesem Buch kurz »Node« genannt.

1.11 Zusammenfassung

Nach diesem Kapitel sollte Ihnen bewusst sein, dass JavaScript nicht eine vereinfachte Version von Java ist, sondern ganz andere Wurzeln hat. Unterschiedliche Ausprägungen der Sprache und verschiedene Standards können Sie nun einordnen. Im nächsten Kapitel werden wir verschiedene Laufzeitumgebungen installieren, um dann praktisch mit JavaScript experimentieren zu können.

2 JavaScript-Laufzeitumgebungen

Nachdem im ersten Kapitel die Geschichte von JavaScript angerissen wurde, befassen wir uns nun mit verschiedenen JavaScript-Laufzeitumgebungen, in denen wir die ersten JavaScript-Programme laufen lassen können. JavaScript ist als interpretierter Code plattformunabhängig. Es gibt Laufzeitumgebungen für nahezu jede Prozessorarchitektur wie x86, ARM oder PowerPC und nahezu jedes Betriebsystem wie Linux, OS X, iOS oder Windows. Die am häufigsten verwendete Laufzeitumgebung ist sicherlich der Webbrowser. Aber JavaScript lässt sich auch »headless«, d. h. außerhalb des Browsers, ausführen. Um die Beispiele der folgenden Kapitel möglichst effektiv (d. h. ohne einen Browser oder eine IDE) nachvollziehen zu können, werden verschiedene Laufzeitumgebungen aufgesetzt, um in diesen Umgebungen mit der Sprache zu exprimentieren.

2.1 JavaScript-Interpreter

JavaScript-Code lässt sich nicht direkt auf einem Mikroprozessor ausführen, sondern wird in der Laufzeitumgebung1 ausgeführt. Diese Laufzeitumgebung kümmert sich um die Wandlung in eine Sprache, die auch ein Mikroprozessor versteht.

Ein Interpreter ist ein Programm, das den Code einliest, ihn analysiert und dann direkt ausführt. Die Analyse erfolgt zur Laufzeit des Programms. Da das Einlesen und die Analyse Zeit benötigen, ist interpretierter Code in der Regel langsamer als direkt ausgeführter Code. Allerdings lässt sich ein Interpreter für beliebige Mikroprozessoren schreiben, sodass interpretierter Code in der Regel plattformunabhängig ist.

Kompilierter Code wird von einem Compiler in Maschinensprache gewandelt. Diese Wandlung wird als Kompilierung bezeichnet. Kompilierter Code ist nicht mehr plattformunabhängig, dafür aber in der Regel schneller als interpretierter Code.

Eine Kompromisslösung zwischen kompiliertem Code und interpretiertem Code ist der Just-in-Time-Compiler (JIT). JITs wandeln Code erst zur Laufzeit in Maschinensprache um. Der Schritt vom JavaScript-Code in Maschinensprache wird also mehrstufig ausgeführt. Dabei wird der Code zunächst in einen optimierten Bytecode gewandelt. Dieser Bytecode wird dann von einem Interpreter oder einem JIT in einer virtuellen Maschine ausgeführt. Die prominenteste virtuelle Maschine ist die Java Virtual Machine (JVM) von Sun Microsystems (heute Oracle). Einige JavaScript-Laufzeitumgebungen verwenden den Ansatz einer virtuellen Maschine, allerdings wird der Bytecode für den Entwickler – anders als bei Java – nicht sichtbar. Er existiert nur innerhalb der Laufzeitumgebung.

2.2 Read-Eval-Print-Loop

Einen Interpreter ruft man in der Regel mit dem Quelltext als Argument auf:

js myScript.js

Das übergebene Skript wird interpretiert und die Ergebnisse werden ausgegeben. Wenn bei der Interpretation ein Fehler auftritt, dann wird das Skript unterbrochen und der Fehler wird ausgegeben.

Der Aufruf eines Interpreters mit dem Quelltext als Argument erlaubt aber keine interaktive Entwicklung. Eine wirklich interaktive Entwicklung ermöglicht die REPL. Der Begriff REPL steht für Read-Eval-Print-Loop und kommt aus dem Lisp-Umfeld. Wenn der User eine Shell startet, befindet er sich meist in einer REPL. Dort kann er Ausdrücke eingeben, die sofort ausgewertet werden. Das Ergebnis wird augenblicklich angezeigt und der Nutzer wird aufgefordert, den nächsten Ausdruck einzugeben. Mehrzeilige Eingaben und Codeblöcke sind in einer REPL unüblich.

Man verwendet eine REPL, um eine neue Sprache zu erlernen oder Programmieransätze direkt in einer Laufzeitumgebung auszuprobieren.

2.3 Der Browser

Die am häufigsten anzutreffende JavaScript-Laufzeitumgebung ist der Webbrowser. Die folgende Übersichtstabelle zeigt die implementierte JavaScript-Version in den gängigsten Browserkonfigurationen:2

JavaScript

ECMA-Script

Firefox

Internet Explorer

Opera

Safari/WebKit

Chrome

1.5

3

1.0

5.5 – 8

6.0 – 10.0

3.0 – 4.0

1

1.6

E4X

1.5

 

 

 

 

1.7

 

2.0

 

 

 

 

1.8

 

3.0

 

 

 

 

1.9

5

4

9a

11

5.0

5

 

5.1

 

10

11.60

5.1b

13

a. Ohne Strict Mode

b. Ohne Function.Prototype.bind-Funktionalität

Dieses Buch handelt jedoch nicht ausschließlich von JavaScript im Browser, sondern auch vom Sprachkern. Daher werden die Unterschiede der verschiedenen Browser in diesem Buch nicht erläutert. Auch auf spezielle Workarounds für den immer noch »beliebten« IE6 wird nicht näher eingegangen.

Wenn man JavaScript möglichst schnell und interaktiv im Browser erforschen möchte, dann bietet sich dazu die Website JSFiddle3 an.

JSFiddle und die Print-Anweisung

Die meisten Beispiele in diesem Buch wurden für JavaScript außerhalb des Browsers entwickelt. In diesen Umgebungen bewirkt eine Print-Anweisung, dass Text auf der Konsole ausgegeben wird. Im Browser (und auch in der Website JSFiddel) bewirkt die Print-Anweisung allerdings, dass der Browser versucht, die Seite auszudrucken. Also ist in den Beispielen die Print-Anweisung durch eine geeignete Anweisung (z. B. console.log() bei aktivierter (Firebug-)Konsole oder alert()) zu ersetzen.

2.4 Headless JavaScript

Wenn man JavaScript ohne Browser nutzt, dann wird dieser Ansatz »Headless JavaScript« genannt. Dieser Ansatz ist nicht neu, denn schon 1996 beinhaltete Netscapes Enterprise Server 2.0 LiveWire, eine serverseitige Laufzeitumgebung für JavaScript. In LiveWire ließ sich JavaScript auch außerhalb des Browsers für serverseitige Anwendungen nutzen. Nachdem der Enterprise Server 2.0 von Sun Microsystems übernommen wurde, wurde JavaScript schon bald durch Java und die Servlet-Technologie abgelöst und Headless JavaScript geriet fast in Vergessenheit. Erst in jüngster Zeit wird JavaScript auch für Anwendungen außerhalb des Browsers wieder interessant.

Wir werden in diesem Kapitel eine Reihe von JavaScript-Laufzeitumgebungen aufsetzen, die auch außerhalb eines Browsers verwendet werden können. Diese Umgebungen haben verschiedene Vor- und Nachteile und unterschiedliche Einsatzgebiete. Wer lediglich eine Laufzeitumgebung installieren möchte, der installiere sich V8 (Abschnitt 2.7). Trotzdem kann es je nach Einsatzgebiet nicht schaden, auch andere Umgebungen zu installieren und mit ihnen herumzuspielen.

2.5 Rhino

Im Rahmen der Sun | Netscape Alliance plante Netscape einen Webbrowser komplett in Java zu entwickeln – den »Javagator«. Obwohl dieser Browser nie die Produktionsreife erreichte, wurde Rhino, eine JavaScript-Laufzeitumgebung vollendet, die JavaScript interpretiert oder in Java-Klassen konvertiert. Rhino stellt also den Kern des nie vollendeten »Javagator« dar. Heute noch wird Rhino von der Mozilla Foundation gepflegt. Seit 2006 wird Rhino zusammen mit Java 6 ausgeliefert. Damit ist Rhino die Laufzeitumgebung, die am häufigsten headless deployt und verwendet wird. Allerdings fehlen Rhino moderne Features.

Rhino unterstützt schon seit der Version 1.3 ECMAScript 3rd Edition. Rhino 1.6 implementiert zudem ECMAScript for XML (E4X). Die aktuelle Version von Rhino ist die Version 1.7, die JavaScript in der Version 1.7 implementiert. Leider ist auch JavaScript 1.7 nicht besonders aktuell. Features aus ECMAScript 5th Edition lassen sich in Rhino nicht nutzen.

Rhino liefert eine interaktive Shell, einen Compiler zum Übersetzen von JavaScript zu Java-Klassen und einen Debugger.

Da Rhino komplett in Java geschrieben ist, empfiehlt sich der Einsatz von Rhino in einer Java-Landschaft, wie man sie oft in Unternehmen antrifft. Rhino hat Zugriff auf sämtliche Java-Bibliotheken. Dies ist ein großer Vorteil für Entwickler, die mit Java und diversen APIs im Java-Umfeld vertraut sind oder die JavaScript in einem Java-Projekt einsetzen möchten.

Eine ältere Version wird mit der Java-Entwicklungsumgebung (JDK) Version 1.6 ausgeliefert. Diese alte Version ist aber nicht nur alt, sondern auch stark beschnitten. Sie unterstützt nicht die Kompilierung von JavaScript hin zu Java-Bytecode und die Erweiterung E4X. Statt der interaktiven Rhino-Shell wird nur das stark abgespeckte JrunScript-Hilfsprogramm mitgeliefert.4 Das Jrun-Hilfsprogramm ist keine interaktive Shell, sondern es kann lediglich JavaScript-Dateien ausführen. Also macht es durchaus Sinn, Rhino auch dann separat zu installieren, wenn man bereits ein aktuelles JDK installiert hat.

Rhino ist inzwischen in die Jahre gekommen. Es verwendet nicht die neuen Features (vor allem Invoke Dynamic), die die Java Virtual Machine seit Java 7 bietet. Daher gibt es das Community-Projekt dyn.js5, das versucht, JavaScript auf Basis von Java neu zu implementieren. Allerdings ist dieses Projekt im Moment noch nicht sehr weit fortgeschritten.