AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert...

30
Manfred Steyer, Vildan Softic AngularJS MODERNE WEBANWENDUNGEN UND SINGLE PAGE APPLICATIONS MIT JAVASCRIPT

Transcript of AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert...

Page 1: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Manfred Steyer, Vildan Softic

AngularJSMODERNE WEBANWENDUNGEN UND SINGLE PAGE APPLICATIONS MIT JAVASCRIPT

Page 2: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Beijing · Cambridge · Farnham · Köln · Sebastopol · Tokyo

AngularJSModerne Webanwendungen und Single Page Applications

mit JavaScript

Manfred Steyer & Vildan Softic

Page 3: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Verlag, Autoren und Übersetzer übernehmen keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene Fehler und deren Folgen.Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind möglicherweise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung,Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

Kommentare und Fragen können Sie gerne an uns richten:O’Reilly VerlagBalthasarstr. 8150670 KölnE-Mail: [email protected]

Copyright:© 2015 by O’Reilly Verlag GmbH & Co. KG

Bibliografische Information Der Deutschen BibliothekDie Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar.

Lektorat: Ariane Hesse, KölnFachlektorat: Florian Helmchen, MünchenKorrektorat: Dorothee Klein, mediaService, SiegenSatz: Gerhard Alfes, mediaService, Siegen, www.mediaservice.tvUmschlaggestaltung: Michael Oreal, KölnProduktion: Andrea Miß, Köln, Karin Driesen, KölnBelichtung, Druck und buchbinderische Verarbeitung: Druckerei Kösel, Krugzell; www.koeselbuch.de

ISBN 978-3-95561-950-3

Dieses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.

Page 4: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

| 3

Inhalt

Vorwort. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1 Paradigmen in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Die prozedurale Seite von JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Die funktionale Seite von JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14Die objektorientierte Seite von JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16Die modulare Seite von JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

2 Einführung in AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31Überblick zu Single Page Applications und AngularJS . . . . . . . . . . . . . . . . . . . . 31Erste Schritte mit AngularJS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35AngularJS näher betrachtet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

3 HTTP-Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77Mit dem Service $http auf Web-Ressourcen zugreifen . . . . . . . . . . . . . . . . . . . . 83REST-Services mit ngResource konsumieren. . . . . . . . . . . . . . . . . . . . . . . . . . . . 103Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

4 Formulare und Validierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115Objekte an Formularfelder binden. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115Eingaben validieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119Benutzerdefinierte Erweiterungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141

Page 5: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

4 | Inhalt

5 Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143Logische Seiten mit ng-switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143Routing mit dem Modul ngRoute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145Routing mit dem externen Modul UI-Router. . . . . . . . . . . . . . . . . . . . . . . . . . . . 158Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

6 Internationalisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173Übersetzungen mit angular-translate nutzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173Länderbezogene Datums- und Zahlenformate mit Globalize unterstützen . . . . . 182Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189

7 Animationen und Touch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191Methoden zum Erstellen von Animationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191Animieren von AngularJS-Kern-Direktiven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197Behandeln von Touch-Interaktionen mit ngTouch . . . . . . . . . . . . . . . . . . . . . . . 202Animationen von der Stange mit Animate.css . . . . . . . . . . . . . . . . . . . . . . . . . . . 204Benutzerdefinierte Direktiven mit Animationen . . . . . . . . . . . . . . . . . . . . . . . . . 206Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210

8 Asynchroner Code mit Promises. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211Überblick zu Promises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212Promises in AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

9 Testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229Jasmine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229Unit-Tests für AngularJS-Konstrukte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232End-2-End Tests mit Protractor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

10 Modularisierung und Verwaltung von Abhängigkeiten mit RequireJS . . . . . . . 261Das JavaScript Modul-Muster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262Verwaltung von Abhängigkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265RequireJS kennenlernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268AngularJS mit RequireJS verwenden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

11 Authentifizierung und Autorisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281Authentifizierung via HTTP BASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281Single Sign On mit OAuth 2.0 und OpenId Connect . . . . . . . . . . . . . . . . . . . . . 286Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

Page 6: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Inhalt | 5

12 Interaktion mit dem Browser. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317Zugriff auf das document-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320Verwenden von $window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323Daten persistieren mit ngCookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325Verzögerte Ausführung mit $interval und $timeout . . . . . . . . . . . . . . . . . . . . . . 328Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331

13 Services näher betrachtet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333Funktionsweise von Services im Detail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333Optionen zum Erstellen von Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337Services direkt mittels Provider erstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340Verwenden eines Decorators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344

14 Benutzerdefinierte Direktiven. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345Eine erste (zu) einfache Direktive. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345Eigener Scope für Direktive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348Isolierte Scopes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349Link-Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352Manuelle Transklusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355Compile-Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356Kommunikation zwischen Direktiven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363

15 User Interface Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365Twitter Bootstrap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365Bootstrap mit AngularJS verwenden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392Datengitter mit ngGrid. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399Kendo UI Grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420

16 Werkzeugunterstützung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421Paket-Verwaltung mit Bower . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422Aufgabenautomatisierung mit Grunt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426Projektvorlagen mit Yeoman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461

Page 7: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine
Page 8: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

| 7

Vorwort

Während für gute Web-Anwendungen vor rund zehn Jahren noch die Regel galt, so vieleAufgaben wie möglich auf dem Server zu erledigen, stützen sich moderne Web-Anwen-dungen auf clientseitige Techniken, allen voran JavaScript. Dies steigert die Benutzer-freundlichkeit und schafft die Möglichkeit der Anpassung an die Auflösungen und Form-faktoren der vielen unterschiedlichen klassischen und mobilen Plattformen.

Single Page Applications (SPA) spiegeln einen derzeit äußerst beliebten Architekturstilfür solche Web-Anwendungen wieder. Wie der Name schon vermuten lässt, bestehensolche Anwendungen aus lediglich einer einzigen Seite, die ein Browser auf klassischemWeg abruft und anzeigt. Alle weiteren Seiten und Daten bezieht die SPA bei Bedarf viaAJAX.

Das populäre JavaScript-Framework AngularJS, welches aus dem Hause Google stammt,hilft bei der Erstellung von Anwendungen, die diesen Architekturstil verfolgen. Es bietetunter anderem Unterstützung für Datenbindung, beim Validieren von Daten oder demArbeiten mit Vorlagen. Darüber hinaus bietet es Konzepte zum Strukturieren von Quell-code sowie zur Schaffung wartbarer, wiederverwendbarer, aber auch gut testbarer Pro-grammteile. Das vorliegende Buch präsentiert die Möglichkeiten von AngularJS. Dabeibeschränkt es sich nicht nur auf die Grundlagen, sondern präsentiert auch Lösungen fürFälle, die das SPA-Framework nicht direkt abdeckt.

ZielgruppeDas Buch richtet sich an Web-Entwickler, die bereits grundlegende Erfahrung mitHTML, CSS und JavaScript haben und nun mit AngularJS Single Page Applications ent-wickeln wollen. Dabei bezieht es sich auf die Version 1.3, welche beim Verfassen derTexte die aktuellste Version war.

Zielsetzung des BuchsZielsetzung dieses Buchs ist es, dem Leser anhand von Beispielen zu zeigen, wie er Angu-larJS zur Entwicklung von Single Page Applications nutzen kann. Dabei geht es auf die

Page 9: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

8 | Vorwort

Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine vollständige Funktionsauflistung verweist es aufdie online vorliegende Dokumentation.

Aufbau des BuchsDas Buch besteht aus 16 Kapiteln. Die nachfolgende Auflistung zeigt, was diese bieten:

Kapitel 1, Paradigmen in JavaScript: Obwohl das vorliegende Buch JavaScript-Kennt-nisse voraussetzt, weist es mit dem ersten Kapitel auf einige Merkmale der Sprache hin,die Entwicklern, die JavaScript bereits benutzt haben, nicht immer geläufig sind. Dazugehört die Beschreibung von funktionalen, objektorientierten und modularen Aspektenwie Closures, Konstruktorfunktionen, Vererbung über Prototypen und dem RevealingModule Pattern. Wer diese Grundlagen beherrscht, kann dieses Kapitel getrost über-springen.

Kapitel 2, Einfühung in AngularJS: Nach einer Diskussion der Ideen hinter SinglePage Applications und des Architekturmusters MVC zeigt dieses Kapitel zunächst dieMöglichkeiten von AngularJS anhand eines Beispiels auf. Danach geht es auf einige Kon-zepte von AngularJS näher ein.

Kapitel 3, HTTP-Services: Die Ideen hinter HTTP sowie das Nutzen von HTTP-basier-ten Ressourcen, wie HTTP-Services, sind Themen dieses Kapitels. Es geht auf die Mög-lichkeiten von $http ein und zeigt, wie Anwendungen REST-basierte Services mit ngRe-source konsumieren können.

Kapitel 4, Formulare und Validierung: Dieses Kapitel zeigt, wie Anwendungen viaAngularJS Daten an Formulare binden und Eingaben validieren können. Dabei geht esauf die Validierungsregeln von AngularJS ebenso ein wie auf die Möglichkeit zur Erstel-lung eigener Validierungsregeln. Daneben zeigt es, wie AngularJS das Konzept der For-matter zum Aufbereiten von Daten für Formularfelder sowie das Konzept der Parser zumÜberführen von Eingaben ins Model nutzt.

Kapitel 5, Routing: Dieses Kapitel zeigt, wie eine Single Page Application dem Benutzermittels Routing verschiedene Seiten, die sie bei Bedarf nachlädt, präsentieren und dabeisowohl Lesezeichen als auch die Nutzung der Schaltfläche Zurück unterstützen kann.Neben dem vom AngularJS-Team angebotenen Modul ngRoute geht es dazu auch auf dasfreie Modul UI-Router ein.

Kapitel 6, Internationalisierung: Das Anpassen von AngularJS-Anwendungen fürBenutzer verschiedener Länder und Sprachen ist Thema dieses Kapitels. Dazu geht es aufdie Nutzung von Übersetzungen mit dem freien Modul angular-translate sowie auf dieArbeit mit verschiedenen Datenformaten unter Verwendung des Frameworks Globalizeein.

Kapitel 7, Animationen und Touch: Um dem Entwickler möglichst einfache Werzeugezum Einbau von Animationen zu bieten, befasst sich dieses Kapitel mit den Funktionen

Page 10: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

| 9

des Moduls ngAnimate und geht insbesondere auf dessen zahlreiche Änderungen in dervorliegenden Version 1.3 ein. Zusätzlich ist auch das Zusammenspiel mit der Anima-tions-Bibliothek animate.css sowie der Einsatz von Touch-Gesten in AngularJS demons-triert.

Kapitel 8, Asynchroner Code mit Promises: Dieses Kapitel geht auf die Notwendig-keit asynchroner Aufrufe in JavaScript ein und zeigt, wie das Konzept der Promises beider Arbeit mit solchen Aufrufen unterstützen kann. Dieses stellt es zunächst anhand derpopulären Bibliothek Q vor. Anschließend zeigt es, wie AngularJS die Ideen von Q mitdem daran angelehnten Service $q verfügbar macht.

Kapitel 9, Testing: Wie die Qualität von AngularJS-Code mit automatisierten Testsgeprüft werden kann, zeigt dieses Kapitel. Es geht dazu auf das Testing-Framework jas-mine ein und zeigt, wie der Entwickler damit isolierte Komponententests für AngularJS-Code schaffen kann. Dazu bespricht es auch das Modul angular-mocks, das dabei unter-stützt. Im Anschluss daran bespricht es die Möglichkeiten zur Schaffung von End-2-End-Tests mit Protractor.

Kapitel 10, Modularisierung und Verwaltung von Abhängigkeiten mit RequireJS:Hinter diesem sperrigen Titel verbirgt sich ein Blick auf Ansätze, mit welchen sich auchgrößere Projekte bewältigen lassen. Dazu stellt das Kapitel Konzepte der Modularisie-rung von JavaScript-Code anhand der Asynchronouos Module Definition (AMD) unterVerwendung von RequireJS vor.

Kapitel 11, Authentifizierung und Autorisierung: Dieses Kapitel zeigt, wie eineAngularJS-Anwendung im Namen des Benutzers auf HTTP-Services zugreifen kann.Dazu geht es auf HTTP BASIC ebenso ein wie auf die Standards OAuth 2.0 und OpenIdConnect, welche unter anderem Single-Sign-On-Szenarien unterstützen.

Kapitel 12, Interaktionen mit dem Browser: In diesem Kapitel sind die Möglichkeitenzur Bearbeitung des DOM-Baums mit jqLite vorgestellt. Anschließend daran sind die vonAngularJS zur Verfügung gestellten Ummantelungen des document- und window-Objektssowie die leichter zu testenden Services $interval und $timeout vorgestellt. Zusätzlichdazu ist das Thema Datenpersistierung mit dem Service ngCookies erläutert.

Kapitel 13, Services näher betrachtet: Die verschiedenen Optionen, um Services inAngularJS zu erstellen, sowie die Erläuterung der zahlreichen Fachbegriffe und wasdahinter steckt, sind das Thema dieses Kapitels. Ein aufbauendes Beispiel hilft zudemverständlich zu machen, wann welche Variante in Betracht zu ziehen ist. Abschließendgeht das Kapitel auf die Verwendung von Dekoratoren sowie deren Möglichkeiten ein.

Kapitel 14, Benutzerdefinierte Direktiven: Dieses Kapitel beschreibt die Schaffungwiederverwendbarer Komponenten, welche unter anderem in Form eigener Attributeund Elemente genutzt werden können.

Kapitel 15, User Interface Design: Da Web-Anwendungen stark visuell geprägt sind,stellt dieses Kapitel mit Twitter Bootstrap ein CSS-Framework für einfache und schöngestaltete Oberflächen ein. Danach zeigt es, wie mit dem Direktiven-Paket Angular UI

Page 11: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

10 | Vorwort

Bootstrap dieses mit AngularJS vereint wird. Den Abschluss bilden die Demonstrationvon zwei Implementierungen eines Datengitters.

Kapitel 16, Werkzeugunterstützung: Im abschließenden Kapitel sind Werkzeuge vor-gestellt, welche die alltägliche Entwicklungsarbeit vereinfachen und zum Teil automati-sieren können. Dazu ist der Frontend-Paket-Manager Bower, das Automatisierungswerk-zeug Grunt sowie der Projektgenerator Yeoman vorgestellt. Anschließend daran ist dasJavaScript Superset TypeScript vorgestellt, welches mit einem statischem Typsystem,Konstrukten wie Interfaces, Klassen, Modulen und Lambda-Ausdrücken aufwartet.

Wie Sie dieses Buch lesen solltenWährend die ersten beiden Kapitel ausgwählte Aspekte von JavaScript sowie eine Ein-führung in AngularJS und dessen Konzepte bietet, widmen sich alle weiteren Kapitel aus-gewählten Themen aus dem Umfeld von AngularJS. Leser, die sich mit den ersten beidenKapiteln oder schon mit den darin vermittelten Aspekten beschäftigt haben, können alleweiteren Kapitel prinzipiell unabhängig voneinander lesen. Da jedoch die einzelnenKomponenten von AngularJS teils sehr stark voneinander abhängen, müssen Sie bei einernicht-sequentiellen Vorgehensweise ggf. den vorherrschenden kapitelübergreifendenVerweisen folgen.

Quellcodebeispiele, Online-Services und ErrataDie Autoren stellen auf www.angular.at sämtliche in diesem Buch präsentierten Quell-codebeispiele sowie Online-Services, die die Beispiele zu Demonstrationszwecken nutzenund auch in eigene Beispiele eingebunden werden können, zur Verfügung. Darüberhinaus werden die Autoren auf dieser Seite weitere Informationen zu AngularJS sowieggf. Errata zum vorliegenden Buch veröffentlichen. Daneben bietet es die Möglichkeit,mit den Autoren direkt in Kontakt zu treten.

DanksagungenUnseren Dank für ihre Mitwirkung an diesem Buch möchten wir aussprechen an

• unsere Familienangehörigen, die uns neben unserem Hauptberuf das Umfeldgeschaffen haben, auch an manchen Abenden und Wochenenden an diesem Bucharbeiten zu können

• die O‘Reilly Lektoren Florian Helmchen und Ariane Hesse, die dieses Buch von derVerlagsseite aus betreut und sprachlich verbessert haben

• Gerhard Alfes von mediaService, die sich um die optischen Aspekte des Buchsgekümmert hat

Manfred Steyer und Vildan Softic, Graz im Januar 2015

Page 12: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

| 11

KAPITEL 1

Paradigmen in JavaScript

Obwohl das vorliegende Werk auf AngularJS fokussiert und JavaScript-Kenntnissevoraussetzt, geht dieses Kapitel auf die in JavaScript vorherrschenden Paradigmen ein.Der Grund dafür ist, dass Entwickler diese kennen sollten, um Frameworks wieJavaScript verstehen und effizient nutzen zu können. Dieser Abschnitt kann und solljedoch kein Ersatz für die einschlägige Literatur zu JavaScript sein, sondern lediglicheinige Konstrukte veranschaulichen, die später im Buch sowie in AngularJS-Projektenimmer wieder genutzt weden. Leser, die bereits die funktionale und objektorientierteSeite von JavaScript kennen und die wissen, wie sie mit JavaScript Vererbung, Moduleund Closures nutzen, können diesen Abschnitt getrost überspringen.

Die prozedurale Seite von JavaScriptDas wohl bekannteste Paradigma, das sich in der Programmiersprache JavaScript wieder-findet, ist der prozedurale Ansatz: Der Entwickler kann Befehle zu Funktionen kombinie-ren und bei Bedarf zur Ausführung bringen. Beispiel 1-1 zeigt ein Beispiel dafür. Es defi-niert die Funktion calcZins. Da es sich bei JavaScript um eine dynamische Sprachehandelt, werden weder die Typen der verwendeten Parameter bzw. Variablen noch derDatentyp des Rückgabewerts festgelegt. Allerdings gehört es zum guten Ton, Variablenmit dem Schlüsselwort var zu deklarieren und ihren Gültigkeitsbereich somit auf dieaktuelle Funktion1 zu beschränken. Dies führt im betrachteten Fall dazu, dass resultlediglich innerhalb der Funktion calcZins bekannt ist. Verwendet der Entwickler eineVariable, ohne sie vorher zu deklarieren, sieht JavaScript sie als globale Variable an. AusGründen der Wartbarkeit sollte der Entwickler jedoch davon absehen. Neuere Versionenvon JavaScript kann er sogar dazu bringen, solche Fälle zu verbieten (mehr Informatio-nen zu diesem Mechanismus, der sich Strict Mode nennt, finden sich später in diesemKapitel im Abschnitt »Die modulare Seite von JavaScript«).

1 Variablen sind unter JavaScript nach ihrer Deklaration mit var tatsächlich innerhalb der gesamten Funktion,in der sie deklariert wurden, sichtbar. Um den Gültigkeitsbereich einer Variablen auf den Block (z.B. auf denSchleifenkörper oder auf den jeweiligen Zweig einer Bedingung) zu beschränken, in dem sie deklariert wurde,bieten neuere JavaScript-Interpreter das Schlüsselwort let (let x = 10; anstatt var x = 10;).

Page 13: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

12 | Kapitel 1: Paradigmen in JavaScript

Beispiel 1-1: Beispiel für eine einfache JavaScript-Funktion

<html><head> <title></title>

<script language="javascript">

function calcZins(k, p, t) { var result = k * p * t / 36000; return result; }

var result = calcZins(200,2,360); alert("Ergebnis: " + result); </script></head>[…]</html>

Ein weiteres Beispiel für eine Funktion in JavaScript bietet Beispiel 1-2. Im Gegensatzzum zuvor betrachteten Beispiel handelt es sich hier um eine Funktion, die eine weitereFunktion aufruft.

Beispiel 1-2: Weitere JavaScript-Funktion

function showZins(k, p1, p2) { var msg = k + " bei ...\n\n";

for (var p = p1; p <= p2; p++) { var zins = calcZins(k, p, 360); msg += " " + p + "% p.a.: " + zins + "\n"; }

alert(msg);}

showZins(500, 1, 3);

Der Entwickler muss nicht sämtliche Parameter beim Aufruf einer Funktion angeben.Parameter, die nicht übergeben wurden, weisen innerhalb der Funktion den Wert unde-fined auf. Da JavaScript-Interpreter die Werte undefined, 0 und null bei logischen Verglei-chen wie false sowie alle anderen Werte wie true behandeln, kann der Entwickler, wie inBeispiel 1-3 gezeigt, sehr einfach prüfen, ob ein Wert (der von den genannten drei Wer-ten abweicht) für einen Parameter vorliegt. Um direkt gegen den Wert undefined zu prü-fen, kann der Entwickler auch, wie mit dem Kommentar in Beispiel 1-3 angedeutet, denOperator typeof heranziehen.

Page 14: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die prozedurale Seite von JavaScript | 13

Beispiel 1-3: Optionale Parameter

function calcZins(k, p, t) {

if (!t) t = 360; // if (typeof t === 'undefined') t = 360;

var result = k * p * t / 36000; return result;}

Der Operator typeof liefert einen String mit einem der folgenden Werte:undefined, object, boolean, number, string, function und xml. Der Wert xmlkommt für Objekte zum Einsatz, die XML-basierende Informationenrepräsentieren. Den Wert object liefert typeof hingegen für alle anderenObjekte und für den Wert null zurück. Um den Typ eines Objekts näherzu bestimmen, kann der Entwickler, wie das vorliegende Kapitel späternoch zeigt, den Operator instanceof heranziehen.

Neben der Möglichkeit, benutzerdefinierte Funktionen zu erstellen, bietet JavaScriptauch einen Satz an vordefinierten Funktionen (Beispiel 1-4): parseInt wandelt eine Zei-chenkette in einen Integer-Wert um. Sie nimmt den umzuwandelnden Wert und dieBasis des Zahlensystems entgegen. Für das Dezimalsystem ist 10 zu übergeben. Auchwenn die Angabe der Basis optional ist und in den meisten Fällen vom Dezimalsystemauszugehen ist, kann die explizite Angabe der Basis einige Probleme verhindern. Bei-spielsweise nutzen ältere Browser beim Vorhandensein einer führenden Null das Oktal-system und somit die Basis 8. Deswegen ist die Angabe dieses Parameters gute Praxis. BeiparseFloat handelt es sich hingegen beim Zieldatentyp um eine Fließkommazahl. DieFunktion String erzeugt einen String und isNaN prüft, ob es sich beim übergebenen Ele-ment um keine Zahl (Not a Number) handelt. Zu den »Nicht-Zahlen« gehören zum Bei-spiel Strings, aber auch zum Beispiel nicht definierte Werte, wie zum Beispiel das Ergeb-nis einer Division durch Null.

Beispiel 1-4: Ausgewählte vordefinierte Funktionen

var two = parseInt("2", 10);var twoPointTwo = parseFloat("2.2");var someString = String(two + twoPointTwo);alert(someString);

var isSevenNaN = isNaN("seven");alert("isSevenNaN: " + isSevenNaN);

var isThisNaN = isNaN(1 / 0);alert("isThisNaN: " + isSevenNaN);

var is42NaN = isNaN(42);alert("is42NaN: " + is42NaN);

Page 15: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

14 | Kapitel 1: Paradigmen in JavaScript

Die Operatoren == und != gehen auch dann von Gleichheit aus, wenn diebeiden Werte nach einer Typumwandlung gleich sind. Aus diesem Grundliefert der Ausdruck ("5" == 5) den Wert true. Möchte der Entwickler diesverhindern, kann er auf die Operatoren === und !== zurückgreifen, wel-che sowohl den Inhalt als auch die Typen vergleichen.

Die funktionale Seite von JavaScriptDie Tatsache, dass es sich bei JavaScript auch um eine funktionale Sprache handelt,dürfte weniger bekannt sein. Beispiel 1-5 demonstriert dies. Die Funktion forEach erwar-tet zwei Parameter: ein Array sowie eine Funktion, die für jeden Eintrag im Array aufzu-rufen ist. Dies ist möglich, da unter JavaScript Funktionen gleichzeitig auch Objektesind. Als solche kann der Entwickler sie Variablen zuweisen, aber auch an andere Funkti-onen weiterreichen.

Bei showItem handelt es sich um eine weitere Funktion, die den übergebenen Wert dar-stellt und myInts ist ein Array mit vier vordefinierten Werten, wobei hier auffällt, dassJavaScript-Arrays eckige Klammern verwendet. Interessant wird es, wenn man den Auf-ruf von forEach betrachtet: Als erstes Argument übergibt das betrachtete Beispiel dasArray, als zweites die Funktion showItem. Hätte der Entwickler an dieser Stelle stattdes-sen showItem() (man achte auf die runden Klammern) geschrieben, würde der JavaScript-Interpreter die Funktion an dieser Stelle ausführen und ihren Rückgabewert an forEachübergeben.

Beispiel 1-5: Die Funktion forEach erwartet für den Parameter action eine weitere Funktion

function forEach(ary, action) { for (var i = 0; i < ary.length; i++) { action(ary[i]); }}

function showItem(item) { alert(item);}

var myInts = [1, 2, 3, 4];

forEach(myInts, showItem);

Der Entwickler kann Funktionen, die er an andere Funktionen übergibt, auch an Ort undStelle definieren, ohne einen Funktionsnamen zu vergeben (Beispiel 1-6). Danebenbesteht auch die Möglichkeit, Variablen Funktionen zuzuweisen (Beispiel 1-7). Behan-delt eine Anwendung eine Variable wie eine Funktion, indem sie ihr runde Klammernnachstellt, bringt der JavaScript-Interpreter die Funktion zur Ausführung, auf die dieVariable verweist.

Page 16: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die funktionale Seite von JavaScript | 15

Beispiel 1-6: Anonyme Funktion

forEach(myInts, function (item) { alert(item); });

Beispiel 1-7: Variablen können auf Funktionen verweisen

var fn = function (item) { alert(item);}

forEach(myInts, fn);fn("Hallo Welt");

Beim Einsatz des Schlüsselworts function bildet JavaScript einen sogenannten Closure(Funktionsabschluss). Das bedeutet, dass Funktionen Zugriff auf alle Variablen haben,die sich in sämtlichen übergeordneten Gültigkeitsbereichen (Scopes) befinden.

Die Funktion createLamp in Beispiel 1-8 erzeugt zum Beispiel eine neue Funktion, die sieder Variable controller zuweist. Diese Funktion hat nun Zugriff auf die Variable dimFac-tor, da sie in einem übergeordneten Gültigkeitsbereich definiert wurde. Deswegen, sowieaufgrund der Tatsache, dass controller diese Funktion zurückliefert, verwirft der Interpre-ter diese lokale Variable nicht nach der Ausführung von createLamp. Vielmehr kommtsie bei jedem Aufruf dieser zurückgelieferten Funktion zum Einsatz (Beispiel 1-91.9). Aufdiese Weise kann der Entwickler eine private Variable schaffen, die im betrachteten Fallnur dieser Funktion zur Verfügung steht und außerhalb dieser nicht existiert.

Beispiel 1-8: Definition von Closures

function createLamp(lampId) { var dimFactor = 0;

var controller = function (command) { switch (command) { case 'dimUp': if (dimFactor < 100) { dimFactor = dimFactor + 10; } alert(lampId + ": " + dimFactor); break;

case 'dimDown': if (dimFactor > 0) { dimFactor = dimFactor - 10; } alert(lampId + ": " + dimFactor); break;

case 'dimFactor': default:

Page 17: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

16 | Kapitel 1: Paradigmen in JavaScript

return dimFactor;

} }

return controller;}

Beispiel 1-9: Einsatz von Closures

var lamp1 = createLamp("Lamp #1");var lamp2 = createLamp("Lamp #2");

lamp1("dimUp");lamp1("dimUp");lamp1("dimUp");lamp1("dimDown");

lamp2("dimUp");

Die objektorientierte Seite von JavaScriptDieser Abschnitt widmet sich der objektorientierten Seite von JavaScript. Dazu zeigt erMöglichkeiten zum Definieren von Objekten und Konstruktorfunktionen, die eine Alter-native zu Klassen darstellen. Daneben erörtert dieser Abschnitt auch Möglichkeiten zurErstellung von Vererbungshierarchien in JavaScript sowie Ansätze zum Erstellen vonNamensräumen.

Objekte mit Objekt-Literalen beschreibenDie einfachste Möglichkeit zum Definieren von Objekten stellt der Einsatz von soge-nannten Objekt-Literalen dar (Beispiel 1-10). Der Entwickler beschreibt dabei Objektedurch geschweifte Klammern und Objekteigenschaften in Form von Name/Wert-Paaren,die durch einen Doppelpunkt zu trennen sind. Bei den Werten kann es sich um atomareWerte handeln (z.B. Strings), um weitere Objekte (in geschweiftem Klammern) oder umArrays (in eckigen Klammern). Dasselbe gilt für Werte, die sich innerhalb von Arrayswiederfinden.

Beispiel 1-10: Objekte mit JSON beschreiben

var flugBuchung = { von: "Graz", nach: "Mallorca", passagiere: [ { vorname: "Max", nachname: "Mustermann" }, { vorname: "Susi",

Page 18: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die objektorientierte Seite von JavaScript | 17

nachname: "Sorglos" } ], bezahlung: { art: "Kreditkarte", betrag: 250, bezahlt: true }};

alert(flugBuchung.Von + " - " + flugBuchung.nach);alert("Bezahlt: " + flugBuchung.Bezahlung.bezahlt);alert("Anzahl Passagiere: " + flugBuchung.passagiere.length);alert("Nachname 1. Passagier: " + flugBuchung.passagiere[0].nachname);

KonstruktorfunktionenAnders als die meisten objektorientierten Sprachen kennt JavaScript das Konzept vonKlassen nicht. Zumindest nicht in der durch den Standard ECMAScript 5 beschriebenenVersion, welche, als dieser Text verfasst wurde, die aktuelle Version war. Die folgendeVersion 6 wird hingegen Klassen kennen.

Als Alternative dazu kommen hier sogenannte Konstruktorfunktionen zum Einsatz (Bei-spiel 1-11). Eine Konstruktorfunktion hat die Aufgabe, ein Objekt zu erzeugen. Dazuweist sie jene Eigenschaften, die das zu erzeugende Objekt aufweisen soll, der Pseudova-riablen this zu. Eigenschaften können dabei auch auf Funktionen (Methoden) verweisen,die das zu erzeugende Objekt anbieten soll. Da sich der Wert von this im Zuge der Aus-führung der Konstruktorfunktion ändern kann, hat es sich eingebürgert, dessen Wert amBeginn der Funktion in einer anderen Variable abzulegen und fortan diese zu verwenden.

Beispiel 1-11 definiert zur Demonstration eine Konstruktorfunktion Person, welche dieVariable self als Ersatz für this verwendet und dem zu erzeugenden Objekt die Eigen-schaften vorname, nachname sowie vollerName zuweist, wobei letztere auf eine Funktionverweist.

Um ein Objekt mit einer Konstruktorfunktion zu erzeugen, ist die Funktion, wie amEnde von Beispiel 1-11 gezeigt, unter Verwendung des Operators new aufgerufen. DasBeispiel weist das Ergebnis der Variable rudi zu. Über den Punktoperator greift esanschließend auf die Eigenschaften des Objekts zu. Im diesem Zuge kommt die FunktionvollerName zur Ausführung.

Beispiel 1-11: Konstruktorfunktion

function Person(vorname, nachname) { var self = this; self.vorname = vorname; self.nachname = nachname;

self.vollerName = function () { return self.vorname + " " + self.nachname;

Page 19: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

18 | Kapitel 1: Paradigmen in JavaScript

}}

var rudi = new Person("Rudolf", "Rentier");alert(rudi.vorname);alert(rudi.nachname);alert(rudi.vollerName());

Jene Eigenschaften, die die Konstruktormethode an this zuweist, sind öffentlich – jederhat darauf Zugriff. Um private Member, auf die im Fall von JavaScript lediglich dasObjekt selbst Zugriff hat, zu definieren, sollte man sich daran erinnern, dass mit demSchlüsselwort function ein Closure erzeugt wird, der seinen Kontext einschließt (vgl. »Diefunktionale Seite von JavaScript«).

Eine Variable, die der Entwickler innerhalb der Konstruktorfunktion definiert, kannsomit auch sämtliche Funktionen des erzeugten Objekts verwenden. Ein Beispiel dafürfinden Sie in Beispiel 1-12. Während es die Eigenschaft inhaber über this zweist und essomit öffentlich ist, handelt es sich bei guthaben und protokoll um Variablen der Kon-struktorfunktion. Somit sind sie außerhalb dieser nicht sichtbar, die einzelnen Funk-tionen des erzeugten Objekts haben jedoch Zugriff darauf. Beispiel 1-13 demonstriert dieVerwendung dieser Konstruktorfunktion sowie des damit erzeugten Objekts.

Beispiel 1-12: Konstruktorfunktion für Objekt mit öffentlichen und privaten Eigenschaften

function Konto(inhaber, startGuthaben) { var self = this; self.inhaber = inhaber; var guthaben = startGuthaben; var protokoll = [];

var addToProtocol = function (action, betrag, text) {

// push fügt ein neues Element am Ende des Arrays ein

protokoll.push({ aktion: "ein", betrag: betrag, text: text }); }

self.einzahlen = function (betrag, text) { addToProtocol("EIN", betrag, text); guthaben += betrag; }

self.abheben = function (betrag, text) { addToProtocol("AUS", betrag, text); guthaben -= betrag; };

Page 20: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die objektorientierte Seite von JavaScript | 19

self.getGuthaben = function () { return guthaben; }

self.getProtokoll = function () { return protokoll; }

}

Beispiel 1-13: Verwenden einer Konstruktorfunktion

var myKonto = new Konto("Susi Sorglos", 200);

myKonto.einzahlen(50);myKonto.abheben(30);

var guthaben = myKonto.getGuthaben();var protokoll = myKonto.getProtokoll();

// Sinnlos, denn das vom Konto verwendete Guthaben ist// in einer anderen Variablen 'guthaben' gespeichert ...// myKonto.guthaben = 33;

alert(guthaben);

Während sich die Deklaration von Methoden innerhalb von Konstruktor-funktionen positiv auf die Lesbarkeit des Quellcodes auswirken kann,kann diese Vorgehensweise bei Konstruktorfunktionen, mit denen eineVielzahl an Objekten erzeugt werden, zu Performance-Einbußen führen.Der Grund dafür liegt darin, dass die Konstruktorfunktion pro Objekt undMethode ein eigenes Funktionsobjekt anlegt. Abhilfe schafft die Nutzungvon Prototypen. Ein Beispiel dafür findet sich im Abschnitt »Vererbung«.

Objekte als DictionariesEin weiteres wissenswertes Detail zu Objekten unter JavaScript ist die Tatsache, dassdiese streng genommen assoziative Arrays, auch Dictionaries genannt, sind, die dieNamen der Eigenschaften auf deren Werte abbilden. Beispiel 1-14 demonstriert dies. Esgreift auf die Eigenschaften eines Kontos sowohl über den Punktoperator als auch überdie von Arrays bekannte Schreibweise zu. Da es sich hierbei jedoch um ein assoziativesArray handelt, kommen für die Indizes Zeichenfolgen zum Einsatz.

Beispiel 1-14: Objekte als assoziative Arrays nutzen

// Objekte sind assoziative Arrays ("Dictionaries")

alert(myKonto.inhaber);alert(myKonto["inhaber"]);

Page 21: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

20 | Kapitel 1: Paradigmen in JavaScript

alert(myKonto.getGuthaben());alert(myKonto["getGuthaben"]());

Dies bedeutet aber auch, dass man lediglich ein Objekt anlegen muss, um ein assoziativesArray zu erhalten. Um sämtliche Schlüssel zu ermitteln, zieht der Entwickler die in Bei-spiel 1-15 gezeigte for...in-Schleife heran. Diese Schleife iteriert jedoch nicht die Werte,sondern die Menge der Schlüssel. Deswegen muss der Programmcode im betrachtetenFall die Werte durch erneuten Zugriff auf das Array via punkte[key] in Erfahrung bringen.

Beispiel 1-15: Objekte sind assoziative Arrays

var punkte = {};

punkte["max"] = 99;punkte["susi"] = 111;

alert(punkte["max"]);

for (var key in punkte) { alert(key + ": " + punkte[key]);}

Neuere Browser, die sich an den Standard ECMAScript 5 orientieren (siehehttp://kangax.github.io/compat-table/es5/#Object.keys), unterstützen aucheine Funktion Object.keys, welche die Eigenschaften eines übergebenenObjekts retourniert.

VererbungZum Aufbau von Vererbungshierarchien bietet sich unter JavaScript unter anderem dieVerwendung von Prototypen an. Ein Prototyp ist ein Objekt, welches der Programmcodeeiner Konstruktorfunktion zuweist. Kann der JavaScript-Interpreter eine Eigenschaft ineinem Objekt nicht finden, durchsucht er dessen Prototyp (genauer: den Prototyp derKonstruktorfunktion). Wird er auch dort nicht fündig, setzt er die Suche beim Prototypdes Prototyps fort. Dieses Vorgehen setzt er fort, bis er an der Spitze der Prototypketteangekommen ist.

Beispiel 1-16 spendiert auf diesem Weg der von JavaScript vorgegebenen Konstruktor-funktion Array eine zusätzliche Funktion each. Instanziiert der Entwickler nun ein neuesArray-Objekt und ruft er bei diesem die Funktion each auf, so wird der JavaScript-Inter-preter innerhalb dieses Objekts nicht fündig. Aus diesem Grund durchsucht er anschlie-ßend den Prototyp und stößt auf die dort eingerichtete Funktion, die er daraufhin aus-führt.

Beispiel 1-16: Den Prototyp einer bestehenden Klasse erweitern

Array.prototype.each = function (fn) { var ary = this;

Page 22: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die objektorientierte Seite von JavaScript | 21

for (var i = 0; i < ary.length; i++) { fn(ary[i]); }}

var myArray = new Array(3, 2, 1);

myArray.each(function (item) { alert(item); });

var ok = myArray instanceof Array;

Um herauszufinden, ob ein Objekt im Sinne von Prototypen einen bestimmten Typ auf-weist, kann der Entwickler den Operator instanceof verwenden. Das betrachtete Listingprüft damit, ob es sich bei der Variable myArray um ein Objekt des Typs Array handelt.Dies ist dann der Fall, wenn myArray direkt vom Typ Array ist oder wenn sich Array inder Kette der Prototypen von myArray befindet.

Bei der Verwendung von Prototypen ist darauf zu achten, dass sämtliche Objekte einesTyps auf ein und dasselbe Prototypobjekt verweisen. Weist der Prototyp einen Zustandauf, haben sämtliche damit über die Prototypenkette in Verbindung stehenden ObjekteZugriff. Attribute, auf die das nicht zutreffen soll, sind somit erneut im erbenden Objektzu definieren. Für vom Prototyp geerbte Funktionen gilt dies jedoch nicht, da JavaScriptden Wert this bei der Ausführung einer Funktion im Prototyp nach wie vor auf daseigentliche Objekt zeigen lässt. Somit nutzen Funktionen, die sich im Prototyp befinden,den Zustand des gerade verwendeten Objekts.

Ein weiteres Beispiel für die Umsetzung von Vererbung findet sich in Beispiel 1-17. Esstellt die Vererbung zunächst ohne die Verwendung von Prototypen her. Stattdessen ruftdie Konstruktorfunktion GiroKonto die Konstruktorfunktion Konto auf. Dies geschiehtjedoch nicht auf dem herkömmlichen Weg, sondern durch Verwendung der Funktioncall. An diese übergibt der Entwickler als ersten Parameter jenen Wert, der im Rahmender Abarbeitung von Konto über this erreichbar sein soll. Da das betrachtete Beispiel dasthis von GiroKonto übergibt, richtet die aufgerufene Funktion Konto im Objekt, das dieKonstruktorfunktion GiroKonto erzeugt, jene Eigenschaften ein, die auch ein Konto auf-weist. Somit existieren sämtliche Eigenschaften des Kontos auch im GiroKonto-Objekt.Dies bewirkt, dass jedes GiroKonto-Objekt seinen eigenen Kontostand hat, anstatt sichgemeinsam mit allen anderen GiroKonto-Objekten den Kontostand des Prototyps teilenzu müssen. Der Aufruf der Konstruktorfunktion Konto führt auch zur Initialisierung dervon Konto geerbten Aspekte.

Zusätzlich definiert das betrachtete Beispiel für Girokonten eine eigene Funktion abhe-ben und überschreibt somit die geerbte. Da diese Funktion jedoch jene, die sie über-schrieben hat, aufruft, sichert das betrachtete Beispiel davor den Wert von abheben,indem es abheben der Variablen base_abheben zuweist.

Der Vollständigkeit halber legt das hier diskutierte Beispiel eine neue Instanz von Kontoals Prototyp von GiroKonto fest. Da die Konstruktorfunktion GiroKonto die Konstruk-torfunktion Konto aufruft und somit GiroKonto-Objekte sämtliche Eigenschaften eines

Page 23: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

22 | Kapitel 1: Paradigmen in JavaScript

Kontos besitzen, wäre dies hier nicht zwingend notwendig. Allerdings erlaubt dies demEntwickler, zur Laufzeit über instanceof herauszufinden, dass ein GiroKonto auch einKonto ist. Daneben erhält auf diese Weise jedes GiroKonto auch jene Funktionen, die dasBeispiel – analog zu Beispiel 1-16 – nachträglich dem Prototyp von Konto hinzufügt.Beim nachträglichen Hinzufügen von Funktionen auf diese Art muss der Entwicklerjedoch beachten, dass solche Funktionen keinen Zugriff auf über Closures realisierte pri-vate Variablen haben. Eine solche Variable ist beispielsweise der Kontostand.

Beispiel 1-17: Vererbung über Prototypen

function GiroKonto(inhaber, startGuthaben, limit) { var that = this; Konto.call(this, inhaber, startGuthaben);

var base_abheben = that.abheben;

that.abheben = function (betrag, text) { base_abheben(betrag, "*" + text + "*"); }}

GiroKonto.prototype = new Konto();

var gk = new GiroKonto("susi", 100, 300);gk.abheben(99, "test");alert(gk.getGuthaben());

Das Beispiel in Beispiel 1-18 demonstriert eine Alternative zur Realisierung der Verer-bung über Prototypen. Bei dieser Variante besteht keine Möglichkeit, private Membermit den Mitteln der funktionalen Programmierung nachzubilden, weswegen die weiterenAbschnitte dieses Kapitels diese Schreibweise auch nicht nutzen. Jeder Member ist beidieser Variante öffentlich, wobei Member, die Konsumenten der Klasse nicht verwendensollen, mit einem initialen Unterstrich gekennzeichnet sind. Dies hindert den Konsumen-ten aber nicht daran, diese Member zu nutzen. Es stellt lediglich eine Darstellungskon-vention dar.

Die Konstruktorfunktionen richten bei dieser Variante lediglich die Attribute des Objektsein. Die Funktionen finden sich hingegen im Prototyp wieder. Dies ist bei der Konstruk-torfunktion Konto ein Objekt vom Typ Object und beim GiroKonto ein Objekt vom TypKonto. Die Konstruktorfunktion GiroKonto ruft wie im letzten Beispiel über call die Kon-struktorfunktion Konto auf und übergibt dabei ihr eigenes this. Dies hat zur Folge, dassdas GiroKonto dieselben Eigenschaften wie das Konto erhält. Somit ist sichergestellt,dass jedes GiroKonto einen eigenen Inhaber, ein eigenes Guthaben und ein eigenes Proto-koll hat. Würde der Entwickler an dieser Stelle die Funktion Konto nicht aufrufen, würdejede GiroKonto-Instanz auf die Member des Prototyps verweisen.

Die Funktionen des Girokontos findet JavaScript über die Prototypenkette. Da beim Auf-ruf von Funktionen innerhalb der Prototypen die Pseudovariable this jedoch immer auf

Page 24: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die objektorientierte Seite von JavaScript | 23

das eigentliche Objekt und nicht auf einen der Prototypen verweist, nutzen diese Funk-tionen den Zustand des Girokontos.

Beispiel 1-18: Alternative Variante zur Vererbung über Prototypen

function Konto(inhaber, startGuthaben) { this._inhaber = inhaber; this._guthaben = startGuthaben; this._protokoll = [];}

Konto.prototype._addToProtocol = function (action, betrag, text) { // push fügt ein neues Element am Ende des Arrays ein this._protokoll.push({ aktion: "ein", betrag: betrag, text: text });}

Konto.prototype.einzahlen = function (betrag, text) { this._addToProtocol("EIN", betrag, text); this._guthaben += betrag;}

Konto.prototype.abheben = function (betrag, text) { this._addToProtocol("AUS", betrag, text); this._guthaben -= betrag;};

Konto.prototype.getGuthaben = function () { return this._guthaben;}

Konto.prototype.getProtokoll = function () { return this._protokoll;}

function GiroKonto(inhaber, startGuthaben, limit) { Konto.call(this, inhaber, startGuthaben);}

GiroKonto.prototype = new Konto();

// abheben sichern, da die nachfolgende Zeile es überschreibt GiroKonto.prototype.base_abheben = GiroKonto.prototype.abheben;

GiroKonto.prototype.abheben = function (betrag, text) { if (betrag <= this._guthaben) { this.base_abheben(betrag, "*" + text + "*"); }}

var gk = new GiroKonto("susi", 100, 300);

Page 25: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

24 | Kapitel 1: Paradigmen in JavaScript

gk.abheben(90, "test");alert(gk.getGuthaben());

Elemente mit Namespaces organisierenStandardmäßig landet bei JavaScript jede Variable im globalen Namensraum. Währendandere Programmiersprachen Möglichkeiten zum Organisieren von Konstrukten inbenannten Namensräumen bieten, existiert solch ein Sprachmerkmal in JavaScript nicht– zumindest nicht in der hier betrachteten Version, die durch den Standard ECMAScript 5beschrieben wird. Für die folgende Version 6 wurde hingegen ein Modul-System ange-kündigt. Durch die Nutzung von Objekten kann der Entwickler dieses Konzept jedoch insämtlichen JavaScript-Versionen nachbilden. Beispiel 1-19 bildet auf diese Weise einenNamespace sample.oop.konto nach. Eine weitere Möglichkeit zum Definieren vonNamensräumen bespricht der Abschnitt »Die modulare Seite von JavaScript«.

Beispiel 1-19: Namespaces über Objekte nachbilden

// Definitionsample = {};sample.oop = {};sample.oop.konto = {};sample.oop.konto.GiroKonto = GiroKonto;sample.oop.konto.Konto = Konto;sample.oop.konto.Dauerauftrag = function (von, zu, betrag) {

var self = this;

self.von = von; self.zu = zu; self.betrag = betrag;

self.ausfuehre = function () { // what ever ... }}

// Verwendung

var kto = sample.oop.konto; // Alias

var gk = new kto.GiroKonto("Susi Sorglos", 200, 200);gk.einzahlen(50, "Taschengeld von der Oma ...");

Ausgewählte vordefinierte ObjekteUm nicht ganz bei null starten zu müssen, bietet JavaScript dem Entwickler einige vorde-finierte Objekte. Eine gute Übersicht darüber sowie eine detaillierte Referenz sämtlicherFunktionen findet man auf https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe-rence/Global_Objects. Dieser Abschnitt behandelt drei ausgewählte Objekte, die manständig benötigt: String, Date und Array.

Page 26: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die objektorientierte Seite von JavaScript | 25

Ein Beispiel für die Verwendung von String finden Sie in Beispiel 1-20. Es zeigt, dass dieInstanziierung eines String-Objekts mittels new dasselbe ist wie das Zuweisen einesneuen Strings. Daneben zeigt es, dass length die Länge des Strings wiederspiegeln kannund substr ein Teil aus der Zeichenkette extrahiert. Das erste Argument ist dabei derStartindex, wobei 0 für das erste Zeichen steht, 1 für das zweite etc., und das zweiteArgument spiegelt die Länge des zu extrahierenden Teilstrings wider.

Beispiel 1-20: Mit Strings arbeiten

var str; str = new String("Hallo Welt!");str = "Hallo Welt!"; // kürzere Variante der Zeile darüber

alert("length: " + str.length);alert("" + str.substr(6, 5)); // Ergebnis: Welt

Die Verwendung von Date zeigt Beispiel 1-21. Es erzeugt zunächst ein Date-Objekt, ohneeinen Wert an die Konstruktorfunktion zu übergeben. Aus diesem Grund repräsentiert esden aktuellen Zeitpunkt. Es fällt auch auf, dass Date für sämtliche Teile, welche einDatum ausmachen, einen Getter anbietet. Um diese Werte zu ändern, existieren dazupassende Setter (z.B. now.setDate(1)). Die Funktion getDate liefert den aktuellen Tag(z.B. 20 für den 20. Januar 1900); getMonth liefert den Monat des Datums, wobei sie hierbei 0 zu zählen beginnt.

Darüber hinaus demonstriert das besprochene Beispiel, dass die KonstruktorfunktionDate auch die einzelnen Bestandteile des zu erzeugenden Datums entgegennehmen kann,sowie dass mit toLocaleDateString, toLocaleTimeString und toLocaleString Funktionenexistieren, die das Datum gemäß der am ausgeführten Client definierten Ländereinstel-lungen in Form eines Strings zurückliefern.

Beispiel 1-21: Mit Datumswerten arbeiten

var now = new Date();

var date = now.getDate()var month = now.getMonth() + 1;var year = now.getFullYear();

var day = now.getDay();

var hour = now.getHours();var minute = now.getMinutes();var second = now.getSeconds();

var past = new Date(2000, 0, 1, 5, 6, 7); // 2000-01-01 05:06:07var millis = now.getTime() - past.getTime();

alert("millis: " + millis);

Page 27: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

26 | Kapitel 1: Paradigmen in JavaScript

alert("toLocaleDateString: " + now.toLocaleDateString());alert("toLocaleString: " + now.toLocaleString());alert("toLocaleTimeString: " + now.toLocaleTimeString());

Beispiel 1-22 gibt einen Überblick über die Verwendung von Arrays. Zunächst demonst-riert es, dass die Erzeugung eines Array-Objekts mit der Konstruktorfunktion Array das-selbe bewirkt wie der Einsatz von eckigen Klammern. Da Arrays in JavaScript dynamischwachsen, kann der Entwickler neue Elemente hinten anfügen, indem er einer freienIndexposition ein Element zuweist. Im betrachteten Fall ermittelt das Beispiel zunächstmit length die Länge des Arrays. Da der erste Eintrag mit dem Index 0 assoziiert ist, stelltdiese Länge somit die erste freie Position dar. Das Listing zeigt aber auch, dass man diesauch mit push erledigen kann. Die Funktion pop entfernt hingegen das letzte Elementund liefert es zurück. Analog dazu fügt unshift ganz vorne ein Element ein und shift ent-fernt das erste Element und gibt es zurück.

Beispiel 1-22: Mit Arrays arbeiten

var lotto;

lotto = []; lotto = new Array(); // Führt zum selben Ergebnis wie die Zeile darüber

lotto = [1, 2, 3]; lotto = new Array(1, 2, 3); // Führt zum selben Ergebnis wie die Zeile darüber

lotto = new Array();var len = lotto.length;lotto[len] = 20; // Hinten anhägen

lotto.push(1); // Hinten anhängenlotto.push(10); // Hinten anhängen

var x = lotto.pop(); // Letztes Element entfernen und zurückliefernalert("pop: " + x);

for(var i = 0; i<lotto.length; i++) { console.log(i + ": " + lotto[i]);}

lotto.unshift(999); // Vorne hinzufügenlotto.shift(); // Erstes Element entfernen und zurückliefern

JSON-basierte StringsHTTP-Services übersenden Daten häufig in Form von JSON (json.org). JSON steht fürJavaScipt Object Notation und ist ein Format, das sich an der Grammatik für Objekt-Literale in JavaScript orientiert (vgl. Abschnitt »Objekte mit Objekt-Literalen beschrei-ben«). Somit liegt dem Entwickler nach dem Aufruf des Services ein String vor, der viaJSON ein Objekt beschreibt. Für die Arbeit mit solchen Strings bieten moderne Browser

Page 28: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Die modulare Seite von JavaScript | 27

ein Objekt namens JSON an. Für ältere Browser kann der Entwickler dieses Objekt mitSkripts, die sich unter http://www.json.org/ finden, nachrüsten.

Das Beispiel in Beispiel 1-23 demonstriert den Einsatz des JSON-basiertes Objekts,indem es mit der Funktion parse einen JSON-basierten String in ein Objekt umwandeltsowie aus diesem Objekt danach wieder mit der Funktion stringify einen JSON-basiertenString erstellt. Dabei berücksichtigt es, dass bei JSON-Strings per Definition auch dieNamen der Eigenschaften in doppelten Hochkommata gehalten sind.

Beispiel 1-23: Mit JSON arbeiten

var person = JSON.parse("{\"name\":\"max\", \"adresse\": \"dort\" }");alert(person.name); // maxvar personString = JSON.stringify(person);alert(personString); // {"name":"max","adresse":"dort"}

Eine Herausforderung, die sich beim Arbeiten mit JSON-Strings ergibt, ist die Darstel-lung von Datumswerten, zumal die JSON-Spezifikation nicht festlegt, wie Datumswertezu kodieren sind. Aus diesem Grund kodieren Services Datumswerte häufig als String.Als Format bietet sich ISO 8601 an, das auch in XML zum Einsatz kommt. Beispiel 1-24veranschaulicht den Aufbau eines solchen Strings anhand der Eigenschaft geboren. Erbeinhaltet einen Datumsanteil, eine Uhrzeit sowie ein Zeitzonenoffset, wobei der Datums-anteil von der Uhrzeit durch ein T getrennt ist. Das Offset kann ein positives oder einnegatives Vorzeichen haben. Das hängt davon ab, ob die jeweilige Zeitzone östlich oderwestlich des Nullmeridians liegt. Der Offset +01:00 steht beispielsweise für Mitteleuro-päische Zeit (MEZ). Leider kennt die Funktion JSON.parse dieses Format nicht, weswe-gen sie Strings, die dieses Format verwenden, nicht als Date-Objekte, sondern eben nurals Strings behandeln (Beispiel 1-24).

Beispiel 1-24: Datumswerte sind bei JSON lediglich Strings

var jsonString = "{\"name\":\"max\", \"adresse\": \"dort\", \"geboren\":\"1970-02-10T18:21:49.536+01:00\" }";var person = JSON.parse(jsonString);var isDate = person.geboren instanceof Date; // false

Die modulare Seite von JavaScriptDa Funktionen ihren eigenen Gültigkeitsbereich (engl. Scope) besitzen, kann der Ent-wickler sie zum Definieren von Modulen, die voneinander abgeschottet sind, heranzie-hen. In der Regel soll jedes Modul jedoch nur einmal existieren. Deswegen hat sich hier-für der Einsatz von anonymen Funktionen eingebürgert, die JavaScript sofort nach ihrerDeklaration ausführt. In englischen Quellen ist hierbei auch von Immediately-InvokedFunction Expression, oder kurz IIFE, die Rede.

Der Entwickler nutzt dazu folgende Schreibweise:

(function() { … })();

Page 29: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

28 | Kapitel 1: Paradigmen in JavaScript

Das erste äußere Klammerpaar umschließt die Funktion, das abschließende Klammer-paar bringt es zur Ausführung. Beispiel 1-25 zeigt ein Beispiel dafür. Sowohl die Variableinfo als auch die beiden Funktionen sum und alertInfo sind nur innerhalb des Modulssichtbar – außerhalb des Moduls existieren sie nicht.

Beispiel 1-25: Module über sich selbst ausführende, anonyme Funktionen definieren

(function () { var info = "Hallo Welt"; function sum(a, b) { return a + b; } function alertInfo() { alert(info); }

})();

Da ein Modul, welches lediglich private Inhalte hat, nicht sonderlich nützlich ist, mussder Entwickler einen Weg finden, um ausgewählte Teile des Moduls öffentlich zugäng-lich zu gestalten. Eine Lösung für dieses Problem stellt die Verwendung eines Übergabe-parameters dar. Erhält dieser Parameter ein Objekt übergeben, kann der Code innerhalbdes Modules dieses Objekt um alle Funktionen und Eigenschaften anreichern, die öffent-lich verfügbar sein sollen. Ein Beispiel für dieses Vorgehen, welches man auch alsRevealing Module Pattern bezeichnet, ist in Beispiel 1-26 abgebildet.

Die dort verwendete anonyme Funktion erwartet über den Parameter root ein Objekt.Dieses erweitert es um die Funktionen sum und sayHello. Da das Beispiel das Objekttools an diesen Parameter übergibt, stehen die beiden Funktionen anschließend pertools.sum und tools.sayHello zur Verfügung. Die Variable info, welche sayHello verwen-det, ist hingegen nach wie vor lediglich innerhalb des Moduls definiert und kann somitaußerhalb nicht verändert werden.

Beispiel 1-26: Ausgewählte Elemente veröffentlichen

var tools = {};

(function (root) { var info = "Hallo Welt";

root.sum = function(a, b) { return a + b; } root.sayHello = function() { alert(info); }})(tools);

var sum = tools.sum(1,2);alert(sum);tools.sayHello();

Neuere JavaScript-Interpreter unterstützen einen sogenannten Strict-Modus. Dieser ver-bietet einige Sprachkonstrukte, die in der Vergangenheit immer wieder zu Problemengeführt haben, darunter die Verwendung globaler Variablen ohne deren Deklarationsowie die Funktion eval, welche JavaScript-Code, der in Form eines Strings zu übergebenist, direkt ausführt und so die Tore für Schadcode öffnet.

Page 30: AngularJS - download.e-bookshelf.de · 8|Vorwort Möglichkeiten von AngularJS ein und präsentiert auch Lösungen für Aspekte, die Angu-larJS nicht direkt unterstützt. Für eine

Zusammenfassung | 29

Der Entwickler aktiviert den Strict-Modus, indem er, wie in Beispiel 1-27 demonstriert,in der ersten Zeile einer Funktion einen String mit dem Inhalt use strict definiert. Da essich hierbei lediglich um einen String, den er keiner Variablen zuweist, handelt, hat dieskeinen Seiteneffekt und auch ältere JavaScript-Interpreter haben kein Problem damit.

Auch wenn der Entwickler den Strict-Modus pro Funktion aktivieren kann, hat es sichdoch eingebürgert, dies auf der Ebene von Modulen zu tun.

Beispiel 1-27: Modul im Strict-Modus

(function () { "use strict";

// x = 5; // Fehler …

})();

ZusammenfassungBei JavaScript handelt es sich um eine Sprache, die mehrere Paradigmen in sich vereint.Ein zentrales Element stellt dabei das Konzept der Funktion dar. Es kommt zum Bildenvon Prozeduren ebenso zum Einsatz wie zum Bereitstellen von Objekten und Bilden vonModulen mit abgegrenzten Gültigkeitsbereichen. Darüber hinaus erlauben Funktionendas Erstellen von Closures und somit unter anderem das Steuern der Sichtbarkeit vonVariablen. Anders als klassenbasierte objektorientierte Sprachen nutzt JavaScript in deraktuell vorliegenden Version ECMAScript 5 Konstruktorfunktionen zur Beschreibungvon Objekttypen sowie Prototypenketten zum Realisieren von Vererbungshierarchien.Eine klassenbasierte Alternative, welche lediglich Syntaxzucker (engl. Syntactic Sugar)für die aktuellen Konzepte darstellt, ist für Version 6 geplant.