Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
Lernen Sie JavaScript - umfassender Schritt-für-Schritt-Einstieg in die Programmierung und in JavaScript - direkt losprogrammieren mit viele Beispielen und Übungsprojekten - ansteigender Schwierigkeitsgrad bis zu komplexeren Webanwendungen JavaScript ist das Herzstück fast jeder modernen Webanwendung, von Social Apps wie Twitter bis hin zu browserbasierten Spiele-Frameworks. Obwohl es JavaScript auch Anfängern einfach macht, zu programmieren, ist die Sprache trotzdem flexibel und mächtig genug, um mit ihr umfangreiche und komplexe Anwendungen erstellen zu können. Haverbeke zeigt Ihnen die Details und die Tiefen von JavaScript-Code. Umfangreiche Beispiele, Übungen und Projekte wie ein Browserspiel, eine einfache Programmiersprache und ein Malprogramm geben Ihnen praktisches Wissen zum Schreiben Ihrer eigenen Programme an die Hand. Zuerst lernen Sie die Grundstruktur von JavaScript kennen, Sie arbeiten mit Funktionen und Datenstrukturen. Dann erfahren Sie mehr über Fehlerbehandlung und -behebung, Modularität und asynchrone Programmierung bevor Sie mit der Programmierung für Webbrowser fortfahren. - Organisieren Sie Ihren Code mit objektorientierten Methoden und Techniken der funktionalen Programmierung - Skripten Sie für den Browser und erstellen Sie eine einfache Webanwendungen - Nutzen Sie das DOM effektiv, um mit dem Browser zu interagieren - Nutzen Sie Node.js, um Server und Programme zu erstellen. Die zweite Ausgabe von "Die Kunst der JavaScript-Programmierung" taucht tief in die Sprache JavaScript ein, um Ihnen zu zeigen, wie Sie schönen, effektiven Code schreiben können. Die Aktualisierungen umfassen brandneues Material zu Features wie Klassennotationen, Pfeilfunktionen, Iteratoren, Asynchronisationsfunktionen, Template Strings und Blockscope. Ist es nicht endlich an der Zeit, dass Sie die Sprache des Webs fließend beherrschen?
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 642
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Marijn Haverbeke ist ein begeisterter polyglotter Programmierer. Er hat an einer breiten Palette von Softwaresystemen gearbeitet, von Datenbanken über Compiler bis hin zu Editoren. Außerdem führt er ein kleines Unternehmen rund um seine Open-Source-Projekte.
Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:
www.dpunkt.plus
Marijn Haverbeke
Richtig gut programmieren lernen –Von der ersten Codezeile bis zum eigenen Projekt
Marijn Haverbeke
Lektorat: Melanie Feldmann
Übersetzung & Satz: G&U Language & Publishing Services GmbH, Flensburg, www.GundU.com
Copy-Editing: Alexander Reischert, www.aluan.de
Herstellung: Stefanie Weidner
Umschlaggestaltung: Helmut Kraus, www.exclam.de
Bibliografische Information der Deutschen Nationalbibliothek
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
ISBN:
978-3-86490-728-9
978-3-96088-911-3
ePub
978-3-96088-912-0
mobi
978-3-96088-913-7
1. Auflage 2020
Translation Copyright für die deutschsprachige Ausgabe © 2020 dpunkt.verlag GmbH
Wieblinger Weg 17
69123 Heidelberg
Copyright © 2019 by Marijn Haverbeke. Title of English-language original: Eloquent JavaScript, 3rd Edition: A Modern Introduction to Programming, ISBN 978-1-59327-950-9, published by No Starch Press. German-language edition copyright © 2020 by dpunkt.verlag GmbH. All rights reserved.
Hinweis:
Dieses Buch wurde auf PEFC-zertifiziertem Papier aus nachhaltiger Waldwirtschaft gedruckt. Der Umwelt zuliebe verzichten wir zusätzlich auf die Einschweißfolie.
Schreiben Sie uns:
Falls Sie Anregungen, Wünsche und Kommentare haben, lassen Sie es uns wissen: [email protected]
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 noch Übersetzer 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
Einleitung
Teil IDie Sprache
Kapitel 1Werte, Typen und Operatoren
Kapitel 2Programmstruktur
Kapitel 3Funktionen
Kapitel 4Datenstrukturen: Objekte und Arrays
Kapitel 5Funktionen höherer Ordnung
Kapitel 6Das geheime Leben der Objekte
Kapitel 7Projekt: Ein Roboter
Kapitel 8Bugs und Fehler
Kapitel 9Reguläre Ausdrücke
Kapitel 10Module
Kapitel 11Asynchrone Programmierung
Kapitel 12Projekt: Eine Programmiersprache
Teil IIDer Browser
Kapitel 13JavaScript im Browser
Kapitel 14DOM (Document Object Model)
Kapitel 15Umgang mit Ereignissen
Kapitel 16Projekt: Ein Jump’n’Run-Spiel
Kapitel 17Zeichnen auf Leinwand
Kapitel 18HTTP und Formulare
Kapitel 19Projekt: Editor für Pixelgrafiken
Teil IIINode.js
Kapitel 20Einführung in Node.js
Kapitel 21Projekt: Eine Website zur Wissensvermittlung
Kapitel 22Leistung
Hinweise zu den Übungen
Stichwortverzeichnis
Einleitung
Teil IDie Sprache
1Werte, Typen und Operatoren
1.1Werte
1.2Zahlen
1.3Strings
1.4Unäre Operatoren
1.5Boolesche Werte
1.6Leere Werte
1.7Automatische Typumwandlung
1.8Zusammenfassung
2Programmstruktur
2.1Ausdrücke und Anweisungen
2.2Bindungen
2.3Namen von Bindungen
2.4Die Umgebung
2.5Funktionen
2.6Die Funktion console.log
2.7Rückgabewerte
2.8Ablaufsteuerung
2.9Bedingte Ausführung
2.10While- und do-Schleifen
2.11Einrückungen
2.12for-Schleifen
2.13Eine Schleife abbrechen
2.14Kurzschreibweisen für die Aktualisierung von Bindungen
2.15Werte mithilfe von switch auswählen
2.16Groß- und Kleinschreibung
2.17Kommentare
2.18Zusammenfassung
2.19Übungsaufgaben
3Funktionen
3.1Funktionen definieren
3.2Gültigkeitsbereiche von Bindungen
3.3Funktionen als Werte
3.4Schreibweise von Deklarationen
3.5Pfeilfunktionen
3.6Der Aufrufstack
3.7Optionale Argumente
3.8Closures
3.9Rekursion
3.10Funktionen einführen
3.11Seiteneffekte
3.12Zusammenfassung
3.13Übungen
4Datenstrukturen: Objekte und Arrays
4.1Das Wereichhörnchen
4.2Datenmengen
4.3Eigenschaften
4.4Methoden
4.5Objekte
4.6Veränderbarkeit
4.7Das Tagebuch des Wereichhörnchens
4.8Korrelationen berechnen
4.9Array-Schleifen
4.10Die endgültige Analyse
4.11Arrayologie für Fortgeschrittene
4.12Eigenschaften von Strings
4.13Restparameter
4.14Das Objekt Math
4.15Zerlegung
4.16JSON
4.17Zusammenfassung
4.18Übungen
5Funktionen höherer Ordnung
5.1Abstraktion
5.2Wiederholungen abstrahieren
5.3Funktionen höherer Ordnung
5.4Die Schriftbeispieldaten
5.5Arrays filtern
5.6Transformationen mit map
5.7Zusammenfassungen mit reduce
5.8Komponierbarkeit
5.9Strings und Zeichencodes
5.10Text erkennen
5.11Zusammenfassung
5.12Übungen
6Das geheime Leben der Objekte
6.1Kapselung
6.2Methoden
6.3Prototypen
6.4Klassen
6.5Klassenschreibweise
6.6Abgeleitete Eigenschaften überschreiben
6.7Maps
6.8Polymorphismus
6.9Symbole
6.10Die Iteratorschnittstelle
6.11Get-, Set- und statische Methoden
6.12Vererbung
6.13Der Operator instanceof
6.14Zusammenfassung
6.15Übungen
7Projekt: Ein Roboter
7.1Meadowfield
7.2Die Aufgabe
7.3Persistente Daten
7.4Simulation
7.5Die Route des Postautos
7.6Routen finden
7.7Übungen
8Bugs und Fehler
8.1Die Rolle der Sprache
8.2Strikter Modus
8.3Typen
8.4Tests
8.5Debugging
8.6Fehlerweiterleitung
8.7Ausnahmen
8.8Aufräumen nach Ausnahmen
8.9Selektives Abfangen von Ausnahmen
8.10Assertions
8.11Zusammenfassung
8.12Übungen
9Reguläre Ausdrücke
9.1Reguläre Ausdrücke erstellen
9.2Auf Übereinstimmungen prüfen
9.3Mengen von Zeichen
9.4Teile eines Musters wiederholen
9.5Teilausdrücke gruppieren
9.6Übereinstimmungen und Gruppen
9.7Die Klasse Date
9.8Wort- und String-Grenzen
9.9Alternative Muster
9.10Der Vergleichsmechanismus
9.11Rückverfolgung
9.12Die Methode replace
9.13Gierige Operatoren
9.14RegExp-Objekte dynamisch erstellen
9.15Die Methode search
9.16Die Eigenschaft lastIndex
9.17Eine INI-Datei analysieren
9.18Internationale Zeichen
9.19Zusammenfassung
9.20Übungen
10Module
10.1Module als Bausteine
10.2Pakete
10.3Module
10.4Daten als Code auswerten
10.5CommonJS
10.6ECMAScript-Module
10.7Compiler, Bundler und Minifier
10.8Moduldesign
10.9Zusammenfassung
10.10Übungen
11Asynchrone Programmierung
11.1Asynchronität
11.2Crow Tech
11.3Callbacks
11.4Promises
11.5Fehlschläge
11.6Netzwerke sind schwierig
11.7Kombinationen von Promises
11.8Flooding
11.9Nachrichtenrouting
11.10Async-Funktionen
11.11Generatoren
11.12Die Ereignisschleife
11.13Asynchronitätsbugs
11.14Zusammenfassung
11.15Übungen
12Projekt: Eine Programmiersprache
12.1Der Parser
12.2Der Evaluierer
12.3Sonderformen
12.4Die Umgebung
12.5Funktionen
12.6Kompilierung
12.7Schummeln
12.8Übungen
Teil IIDer Browser
13JavaScript im Browser
13.1Netzwerke und das Internet
13.2Das Web
13.3HTML
13.4HTML und JavaScript
13.5Ausführung in einer Sandbox
13.6Die Browserkriege und das Problem der Kompatibilität
14DOM (Document Object Model)
14.1Die Dokumentstruktur
14.2Bäume
14.3Der Standard
14.4Den Baum durchlaufen
14.5Elemente finden
14.6Das Dokument ändern
14.7Knoten erstellen
14.8Attribute
14.9Layout
14.10Formatierung
14.11CSS
14.12Abfrageselektoren
14.13Positionierung und Animation
14.14Zusammenfassung
14.15Übungen
15Umgang mit Ereignissen
15.1Ereignis-Handler
15.2Ereignisse und DOM-Knoten
15.3Ereignisobjekte
15.4Weiterleitung
15.5Standardaktionen
15.6Tastaturereignisse
15.7Zeigeereignisse
15.8Scrollereignisse
15.9Fokusereignisse
15.10Ladeereignisse
15.11Ereignisse und die Ereignisschleife
15.12Timer
15.13Entprellen
15.14Zusammenfassung
15.15Übungen
16Projekt: Ein Jump’n’Run-Spiel
16.1Das Spiel
16.2Die Technologie
16.3Levels
16.4Ein Level lesen
16.5Akteure
16.6Kapselung als zusätzliche Belastung
16.7Zeichnen
16.8Bewegungen und Kollisionen
16.9Akteure aktualisieren
16.10Tastenbetätigungen verfolgen
16.11Das Spiel ausführen
16.12Übungen
17Zeichnen auf Leinwand
17.1SVG
17.2Das Canvas-Element
17.3Linien und Flächen
17.4Pfade
17.5Kurven
17.6Ein Tortendiagramm zeichnen
17.7Text
17.8Bilder
17.9Transformationen
17.10Transformationen speichern und löschen
17.11Zurück zu unserem Spiel
17.12Auswahl einer Grafikschnittstelle
17.13Zusammenfassung
17.14Übungen
18HTTP und Formulare
18.1Das Protokoll
18.2Browser und HTTP
18.3Fetch
18.4HTTP-Sandboxing
18.5Die Möglichkeiten von HTTP nutzen
18.6Sicherheit durch HTTPS
18.7Formularfelder
18.8Fokus
18.9Deaktivierte Felder
18.10Das Formular als Ganzes
18.11Textfelder
18.12Kontrollkästchen und Optionsschalter
18.13Auswahlfelder
18.14Dateifelder
18.15Clientseitige Datenspeicherung
18.16Zusammenfassung
18.17Übungen
19Projekt: Editor für Pixelgrafiken
19.1Komponenten
19.2Der Status
19.3Aufbau des DOM
19.4Die Leinwand
19.5Die Anwendung
19.6Zeichenwerkzeuge
19.7Speichern und Laden
19.8Der Undo-Verlauf
19.9Die Anwendung einrichten
19.10Warum ist das so schwer?
19.11Übungen
Teil IIINode.js
20Einführung in Node.js
20.1Hintergrund
20.2Der Befehl node
20.3Module
20.4Installation mit NPM
20.5Das Dateisystemmodul
20.6Das HTTP-Modul
20.7Streams
20.8Ein Dateiserver
20.9Zusammenfassung
20.10Übungen
21Projekt: Eine Website zur Wissensvermittlung
21.1Design
21.2Long Polling
21.3Die HTTP-Schnittstelle
21.4Der Server
21.5Der Client
21.6Übungen
22Leistung
22.1Stufenweise Kompilierung
22.2Graphzeichnen
22.3Definition eines Graphen
22.4Kräftebasiertes Graphzeichnen
22.5Arbeit vermeiden
22.6Profiling
22.7Inline-Ersetzung
22.8Weniger überflüssige Objekte erzeugen
22.9Garbage Collection
22.10Dynamische Typen
22.11Zusammenfassung
22.12Übungen
Hinweise zu den Übungen
Stichwortverzeichnis
Für Lotte und Jan
»Wir glauben, dass wir das System zu unserem eigenen Nutzen erstellen. Wir glauben, dass wir es nach unserem eigenen Bilde erschaffen. […] Aber der Computer ist nicht wie wir. Er ist eine Projektion eines sehr kleinen Teils von uns: des Teils, der Logik, Ordnung, Regeln und Klarheit zugetan ist.«
– Ellen Ullman, Close to the Machine: Technophilia and its Discontents (auf Deutsch erschienen als Close to the Machine: Mein Leben mit dem Computer)
In diesem Buch geht es darum, Computern Anweisungen zu geben. Computer sind heutzutage so alltäglich geworden wie Schraubenzieher, allerdings deutlich komplizierter. Deshalb ist es nicht immer einfach, sie auch wirklich das tun zu lassen, was man will.
Wenn Sie Ihren Computer für eine übliche und klar umrissene Aufgabe einsetzen möchten, z.B. um E-Mails anzuzeigen oder Berechnungen wie mit einem Taschenrechner durchzuführen, können Sie einfach die entsprechende Anwendung öffnen und loslegen. Für besondere Aufgaben gibt es dagegen möglicherweise noch keine Anwendung.
An dieser Stelle kommt die Programmierung ins Spiel. Dabei handelt es sich um den Vorgang, ein Programm zu erstellen, also eine Folge genauer Anweisungen, die dem Computer sagen, was er tun soll. Da Computer stumpfsinning und pedantisch sind, ist Programmierung im Grunde zunächst mühselig und frustrierend.
Wenn Sie jedoch darüber hinwegkommen und vielleicht sogar Freude an einer Denkweise in strengen Bahnen finden, die auch eine stumpfe Maschine versteht, kann Programmierung lohnenswert sein. Denn damit lassen sich in Sekunden Dinge erledigen, die sonst ewig dauern würden. Sie bietet eine Möglichkeit, Ihr Werkzeug, den Computer, Aufgaben ausführen zu lassen, die er zuvor nicht beherrschte. Und außerdem ist es eine hervorragende Übung für abstraktes Denken.
Programmierung erfolgt mithilfe einer Programmiersprache. Dabei handelt es sich um eine künstliche Sprache, die dazu dient, Computern Anweisungen zu erteilen. Es ist schon bemerkenswert, dass sich die effektivste Möglichkeit zur Kommunikation mit Computern, die wir erfunden haben, so stark an die Art und Weise anlehnt, wie wir miteinander kommunizieren. Ebenso wie in menschlichen Sprachen können auch in Computersprachen Wörter und Ausdrücke kombiniert werden, um Ideen auszudrücken.
Textschnittstellen wie die BASIC- und DOS-Eingabeaufforderungen der 80er und 90er bildeten einst die Hauptmethode für die Kommunikation mit Computern. Mittlerweile wurden sie größtenteils durch grafische Schnittstellen ersetzt, die leichter zu erlernen sind, aber weniger Freiheiten bieten. Die Computersprachen jedoch sind immer noch vorhanden. Sie müssen nur wissen, wo Sie danach zu suchen haben. Eine dieser Sprachen, nämlich JavaScript, ist in jeden modernen Webbrowser eingebaut und steht daher auf fast jedem Gerät zur Verfügung.
Dieses Buch soll Ihnen helfen, sich so weit mit dieser Sprache vertraut zu machen, dass Sie sie für nützliche und unterhaltsame Zwecke einsetzen können.
Neben JavaScript werde ich auch die Grundlagen der Programmierung erklären. Programmieren ist schwer. Die Grundregeln sind zwar einfach und deutlich, aber die nach diesen Regeln aufgebauten Programme geraten gewöhnlich so vielschichtig, dass sie ihre eigenen Regeln und eine eigene Komplexität aufweisen. In gewissem Sinne bauen Sie ein Labyrinth, in dem Sie sich selbst auch verirren können.
Bei der Lektüre dieses Buches werden Sie sich hin und wieder furchtbar frustriert fühlen. Wenn Programmierung ganz neu für Sie ist, gibt es viel Stoff zu verdauen. Eine Menge dieses Stoffs wird dann auf eine Weise miteinander kombiniert, die es erfordert, zusätzliche Verbindungen herzustellen.
Dazu müssen Sie sich anstrengen. Wenn Sie Schwierigkeiten haben, dem Text zu folgen, dann gehen Sie nicht vorschnell mit sich selbst ins Gericht. Mit Ihnen ist alles in Ordnung – Sie dürfen nur nicht aufgeben! Legen Sie eine Pause ein, lesen Sie etwas erneut und achten Sie darauf, die Beispielprogramme und Übungen nachzuvollziehen und zu begreifen. Lernen ist harte Arbeit. Aber alles, was Sie lernen, gehört zu Ihnen und macht das weitere Lernen einfacher.
»Wenn Aktionen unrentabel werden, sammeln Sie Informationen; wenn Informationen unrentabel werden, legen Sie sich schlafen.«
– Ursula K. LeGuin, The Left Hand of Darknes (auf Deutsch erschienen als Winterplanet und als Die linke Hand der Dunkelheit)
Ein Programm ist vieles zugleich: ein von einem Programmierer geschriebener Text; ein Datenpaket im Arbeitsspeicher des Computers, wo es Aktionen desselben steuert – und damit die lenkende Kraft, die dafür sorgt, dass der Computer das macht, was er tut. Alle Analogien, die Programme mit vertrauten Objekten des Alltags vergleichen, greifen zu kurz. Ein oberflächlicher Vergleich ist der mit einer Maschine: Viele einzelne Teile arbeiten zusammen, damit das Ganze läuft, und wir müssen Möglichkeiten finden, um diese Teile zu verzahnen, damit sie ihren Beitrag zum Funktionieren der Gesamtheit leisten können.
Ein Computer ist eine physische Maschine, die als Wirt solcher immateriellen Maschinen dient. Für sich allein genommen können Computer lediglich ganz einfache Dinge tun. Sie sind nur deshalb so nützlich, weil sie das mit unglaublich hoher Geschwindigkeit erledigen. Ein Programm kann nun auf raffinierte Art und Weise enorme Mengen solcher einfachen Aktionen kombinieren, um so äußerst komplizierte Aufgaben zu erfüllen.
Ein Programm ist ein Gedankenkonstrukt. Seine Erstellung kostet nichts, es ist gewichtslos und wächst rasch, während Sie die Tastatur bearbeiten. Wenn Sie nicht aufpassen, können Größe und Komplexität eines Programms rasch unkontrolliert zunehmen, sodass schließlich selbst die Person, die es geschrieben hat, den Überblick verliert und es nicht mehr richtig versteht. Das größte Herausforderung der Programmierung besteht darin, die Programme unter Kontrolle zu halten. Wenn ein Programm funktioniert, ist es schön. Die Kunst der Programmierung ist die Fähigkeit, die Komplexität im Zaum zu halten. Großartige Programme sind schlicht – also in all ihrer Komplexität möglichst einfach gestaltet.
Manche Programmierer sind der Meinung, dass sie dieser Komplexität am besten Herr werden, indem sie nur einige wenige, gut verstandene Techniken für ihre Programme verwenden. Dazu haben sie strenge Regeln (»empfohlene Vorgehensweisen«, auch »Best Practices«) aufgestellt, die vorschreiben, welche Form Programme haben sollen, und achten sorgfältig darauf, nicht aus dieser eng begrenzten Sicherheitszone auszubrechen.
Das ist jedoch nicht nur langweilig, sondern auch ineffektiv. Neue Probleme erfordern oft neue Lösungen. Programmierung ist eine junge Disziplin, die sich immer noch rasant weiterentwickelt, und sie ist vielgestaltig genug, um Platz für sehr unterschiedliche Vorgehensweisen zu bieten. Es gibt viele furchtbare Fehler, die einem bei der Programmgestaltung unterlaufen können. Sie sollten diese Fehler ruhig machen, damit Sie sie verstehen. Ein Gespür dafür, wie ein gutes Programm auszusehen hat, entwickeln Sie durch praktische Anwendung. Aus einem Satz von Regeln lernen Sie das nicht.
In den Anfangstagen der Computer gab es noch keine Programmiersprachen. Programme sahen damals wie folgt aus:
00110001 00000000 00000000
00110001 00000001 00000001
00110011 00000001 00000010
01010001 00001011 00000010
00100010 00000010 00001000
01000011 00000001 00000000
01000001 00000001 00000001
00010000 00000010 00000000
01100010 00000000 00000000
Allerdings verlieh die manuelle Eingabe dieser obskuren Muster aus Bits (Nullen und Einsen) den Programmierern das tiefe Gefühl, mächtige Zauberer zu sein. Das war schon viel wert, was die Zufriedenheit am Arbeitsplatz anging.
Jede Zeile des vorigen Programms bildet eine einzige Anweisung. Ins Deutsche übersetzt sehen diese Anweisungen wie folgt aus:
Speichere die Zahl 0 am Speicherort 0.
Speichere die Zahl 1 am Speicherort 1.
Speichere den Wert von Speicherort 1 im Speicherort 2.
Subtrahiere die Zahl 11 von dem Wert im Speicherort 2.
Wenn der Wert in Speicherort 2 die Zahl 0 ist, fahre mit Anweisung 9 fort.
Addiere den Wert von Speicherort 1 zu Speicherort 0.
Addiere die Zahl 1 zum Wert von Speicherort 1.
Fahre mit Anweisung 3 fort.
Gib den Wert von Speicherort 0 aus.
Das ist zwar schon besser lesbar als die Bit-Suppe, aber immer noch ziemlich unverständlich. Es wird besser, wenn wir für die Anweisungen und Speicherorte Namen statt Zahlen verwenden:
Set "total" to 0.
Set "count" to 1.
[loop]
Set "compare" to "count".
Subtract 11 from "compare".
If "compare" is zero, continue at [end].
Add "count" to "total".
Add 1 to "count".
Continue at [loop].
[end]
Output "total".
Können Sie erkennen, wie das Programm abläuft? Die ersten beiden Zeilen geben zwei Speicherorten ihre Startwerte: total wird verwendet, um nach und nach das Ergebnis der Berechnung aufzubauen, während sich count jeweils merkt, welche Zahl wir uns gerade ansehen. Die Zeilen, in denen compare verwendet wird, sind wahrscheinlich die absonderlichsten. Das Programm prüft hier, ob count gleich 11 ist, um zu entscheiden, ob es die Ausführung beenden kann. Da unser hypothetischer Computer ziemlich primitiv ist, kann er nur prüfen, ob eine Zahl gleich 0 ist, und seine Entscheidung darauf gründen. Daher verwendet er den Speicherort compare, um den Wert von count - 11 zu berechnen, und stellt den Vergleich damit an. Die nächsten beiden Zeilen addieren den Wert von count zu dem Ergebnis und setzen count um 1 herauf, solange dieser Wert noch ungleich 11 ist.
In JavaScript sieht das gleiche Programm wie folgt aus:
Diese Version bietet einige weitere Verbesserungen. Vor allem haben wir es hier nicht mehr nötig, das Programm ausdrücklich anzuweisen, vor- oder zurückzuspringen. Darum kümmert sich das while-Konstrukt. Es setzt die Ausführung des dahinter stehenden Blocks (in geschweiften Klammern) so lange fort, wie die ihm übergebene Bedingung zutrifft. Diese Bedingung lautet count <= 10, was bedeutet: »count ist kleiner oder gleich 10.« Wir müssen hier nicht mehr einen Zwischenwert berechnen und mit 0 vergleichen, was ohnehin ein für das eigentliche Ziel unbedeutender Detailmechanismus war. Programmiersprachen sind unter anderem deshalb so leistungsfähig, weil sie uns solche uninteressanten Einzelheiten abnehmen. Am Ende des Programms, nach dem Abschluss des while-Konstruktors, sorgt die Operation console.log dafür, dass das Resultat ausgegeben wird.
Wenn uns die bequemen Operationen range und sum zur Verfügung stehen, die eine Zahlenmenge aus einem gegebenen Bereich zusammenstellen bzw. die Summe einer Menge von Zahlen berechnen können, sind wir in der Lage, das Programm wie folgt zu schreiben:
console.log(sum(range(1, 10)));
// → 55
Die Moral von der Geschichte ist, dass sich Programme auf verschiedene Weisen ausdrücken lassen – lang und kurz, unverständlich und verständlich. Die erste Version des Programms war extrem obskur, während die letzte schon fast wie Deutsch aussieht: »Protokolliere die Summe des Bereichs der Zahlen von 1 bis 10.« Wie sich Operationen wie sum und range definieren lassen, werden wir uns in den späteren Kapiteln noch ansehen.
Eine gute Programmiersprache unterstützt Programmierer, indem sie ihnen erlaubt, die groben Aktionen, die der Computer durchführen soll, zu beschreiben, und die Details wegzulassen. Sie stellt komfortable Bausteine bereit (wie while und console.log), ermöglicht die Definition eigener Bausteine (wie sum und range) und erleichtert es, diese Bausteine zu kombinieren.
JavaScript wurde 1995 als eine Möglichkeit eingeführt, um Webseiten im Netscape Navigator Programme hinzuzufügen. Die Sprache wurde seitdem von allen anderen wichtigen grafischen Browsern übernommen. Sie hat moderne Webanwendungen möglich gemacht, mit denen Sie direkt arbeiten können, ohne nach jeder Aktion auf einen neuen Seitenaufbau warten zu müssen. JavaScript wird auch auf herkömmlichen Webseiten eingesetzt, um verschiedenen Formen der Interaktivität und ausgeklügelte Funktionen zu bieten.
Beachten Sie jedoch, dass JavaScript so gut wie nichts mit der Programmiersprache Java zu tun hat. Der Name wurde eher aus Marketinggründen gewählt. Bei der Einführung von JavaScript wurde Java stark angepriesen und nahm an Beliebtheit zu. Jemand hielt es für eine gute Idee, auf der Erfolgswelle mitzuschwimmen. Bei dem Namen ist es dann geblieben.
Nach der Übernahme in andere Browser als Netscape wurde ein Normdokument verfasst, um zu beschreiben, wie sich JavaScript verhalten soll, damit auch tatsächlich immer die gleiche Sprache gemeint ist, wenn Software behauptet, JavaScript zu unterstützen. Dieser Standard wird nach der Organisation Ecma International, die die Normung vorgenommen hat, als ECMAScript bezeichnet. In der Praxis können die Begriffe ECMAScript und JavaScript synonym verwendet werden – es sind zwei Bezeichnungen für dieselbe Sprache.
Manche Personen werden Ihnen fürchterliche Dinge über JavaScript erzählen. Viele davon sind wahr. Als ich zum ersten Mal etwas in JavaScript schreiben musste, lernte ich die Sprache sehr schnell zu hassen. Sie akzeptierte fast alles, was ich eingab, deutete es dann aber völlig anders, als ich es gemeint hatte. Dies lag zu einem großen Teil natürlich auch daran, dass ich damals keine Ahnung hatte, was ich da eigentlich tat. Aber es ist auch das Symptom eines echten Problems: JavaScript ist absurd freizügig. Dahinter stand die Idee, dass es das Programmieren in JavaScript für Anfänger erleichtern würde. In Wirklichkeit aber erschwert dies, Probleme in Programmen zu finden, da das System Sie nicht darauf hinweist.
Diese Flexibilität hat jedoch auch ihre Vorteile. Sie erlaubt viele Techniken, die in strengeren Sprachen unmöglich sind. Wie Sie noch sehen werden (etwa in Kapitel 10), kann sie auch dazu genutzt werden, einige der Mängel von JavaScript auszubügeln. Nachdem ich die Sprache gründlich gelernt und eine Weile damit gearbeitet hatte, begann ich JavaScript sogar zu mögen.
Es gibt verschiedene Versionen von JavaScript. ECMAScript Version 3 war während des Aufstiegs von JavaScript etwa zwischen 2000 und 2010 sehr weit verbreitet. In dieser Zeit wurde an der anspruchsvolleren Version 4 gearbeitet, bei der es einige radikale Verbesserungen und Erweiterungen geben sollte. Es erwies sich jedoch als politisch schwierig, eine lebendige, weiträumig genutzte Sprache so einschneidend zu verändern, weshalb die Arbeiten an Version 4 im Jahre 2008 eingestellt wurden. Stattdessen wurde 2009 die weniger ambitionierte Version 5 veröffentlicht, die nur einige nichtkontroverse Verbesserungen bot. 2015 kam die stark überarbeitete Version 6 heraus, die einige der für Version 4 geplanten Aspekte enthielt. Seitdem gab es jedes Jahr kleinere Aktualisierungen.
Da sich die Sprache weiterentwickelt, müssen die Browser mithalten. Wenn Sie einen älteren Browser verwenden, kann es sein, dass er nicht alle Funktionen unterstützt. Die Entwickler der Sprache achten sorgfältig darauf, keine Änderungen einzuführen, die bestehende Programme funktionsunfähig machen würden. Daher können neue Browser immer noch ältere Programme ausführen. In diesem Buch verwendete ich die JavaScript-Version von 2017.
Browser sind jedoch nicht die einzigen Plattformen, auf denen JavaScript eingesetzt wird. Auch einige Datenbanken wie MongoDB oder CouchDB nutzen JavaScript als Skripterstellungs- und Abfragesprache. Verschiedene Plattformen für die Desktop- und Serverprogrammierung, insbesondere das Projekt Node.js (um das es in Kapitel 20 geht), bieten eine Umgebung für die JavaScript-Programmierung außerhalb des Browsers.
Code ist der Text eines Programms. Die meisten Kapitel dieses Buches enthalten eine Menge Code. Ich bin der Meinung, dass das Lesen und Schreiben von Code unverzichtbar ist, um Programmieren zu lernen. Überfliegen Sie die Beispiele nicht einfach, sondern lesen Sie sie aufmerksam, um sie auch wirklich zu verstehen. Das kann zu Anfang langsam und verwirrend sein. Aber ich verspreche Ihnen, dass Sie den Bogen schon bald heraushaben werden. Das Gleiche gilt auch für die Übungen. Sie haben diese erst dann richtig verstanden, wenn Sie eine Lösung dafür geschrieben haben.
Ich empfehle Ihnen, Ihre Lösungen zu den Übungsaufgaben tatsächlich in einem JavaScript-Interpreter auszuprobieren. Dadurch erhalten Sie unmittelbar eine Rückmeldung, ob sie funktionieren, und werden hoffentlich auch dazu animiert, über die Aufgabenstellung hinaus noch weiter zu experimentieren.
Die einfachste Möglichkeit, den Beispielcode in diesem Buch auszuführen und damit zu experimentieren, besteht darin, ihn in der Online-Version des Buchs auf https://eloquentjavascript.net anzusehen. Dort können Sie auf die Codebeispiele klicken, um sie zu bearbeiten, auszuführen und sich die Ausgaben anzusehen. Um die Übungen zu bearbeiten, besuchen Sie https://eloquentjavascript.net/code. Dort erhalten Sie den Ausgangscode für alle Programmierübungen und können auch einen Blick auf die Lösungen werfen.
Wollen Sie die Programme aus diesem Buch außerhalb der Begleitwebseite ausführen, ist etwas Vorsicht geboten. Viele der Beispiele sind eigenständig und sollten in jeder JavaScript-Umgebung funktionieren. Code in den hinteren Kapiteln ist jedoch oft für eine bestimmte Umgebung geschrieben (den Browser oder Node.js) und kann nur dort ausgeführt werden. Außerdem werden in einigen Kapiteln umfangreichere Programme erstellt, deren einzelne Teile voneinander und manchmal auch von externen Dateien abhängen. Die Sandbox auf der Webseite stellt Links zu Zip-Dateien mit allen Skript- und Datendateien bereit, die erforderlich sind, um den Code zu einem Kapitel auszuführen.
Dieses Buch besteht aus drei Teilen. Die ersten zwölf Kapitel beschreiben die Sprache JavaScript, in den nächsten sieben geht es um Webbrowser und ihre Programmierung mit JavaScript, und die beiden letzten sind Node.js gewidmet, einer weiteren Programmierumgebung für JavaScript.
Über das ganze Buch verstreut sind fünf Projektkapitel, in denen umfangreiche Beispielprogramme beschrieben werden, um Ihnen einen Vorgeschmack auf die tatsächliche Programmierarbeit zu geben. In diesen Kapiteln programmieren wir einen Zustellroboter, eine Programmiersprache, ein Jump’n’Run-Spiel, ein Malprogramm und eine dynamische Webseite.
Der erste Teil des Buches beginnt mit vier Kapiteln, die die Grundstruktur von JavaScript vorstellen. Sie geben eine Einführung in Steuerstrukturen (z. B. das while-Konstrukt, das Sie bereits in dieser Einleitung kennengelernt haben), Funktionen (von Ihnen selbst geschriebene Bausteine) und Datenstrukturen. Damit sind Sie schon in der Lage, einfache Programme zu schreiben. Anschließend werden in den Kapiteln 5 und 6 Techniken eingeführt, um mithilfe von Funktionen und Objekten abstrakteren Code zu schreiben und die Komplexität zu reduzieren.
Nach einem ersten Projektkapitel geht es im ersten Teil des Buches mit Kapiteln über Fehlerbehandlung und -behebung, reguläre Ausdrücke (ein wichtiges Instrument für die Arbeit mit Text), Modularität (eine weitere Maßnahme gegen zu hohe Komplexität) und asynchrone Programmierung (Umgang mit Ereignissen, die einige Zeit dauern) weiter. Das zweite Projektkapitel schließt den ersten Teil ab.
Der zweite Teil – die Kapitel 13 bis 19 – beschreibt die Werkzeuge, auf die JavaScript im Browser Zugriff hat. Sie erfahren hier, wie Sie etwas auf dem Bildschirm darstellen (Kapitel 14 bis 17), wie Sie auf Benutzereingaben reagieren (Kapitel 15) und wie Sie über das Netzwerk kommunizieren (Kapitel 18). Auch in diesem Teil gibt es wieder zwei Projektkapitel.
Im Anschluss daran wird in Kapitel 20 Node.js beschrieben und in Kapitel 21 eine kleine Webseite damit erstellt.
In Kapitel 22 finden Sie schließlich einige Überlegungen dazu, wie Sie JavaScript-Programme optimieren können, um die Ausführung zu beschleunigen.
Text in einer nichtproportionalen Schrift kennzeichnet in diesem Buch Programmelemente – sowohl eigenständige Fragmente als auch »Zitate« aus einem in der Nähe abgedruckten Programm. Die Programme selbst (von denen Sie inzwischen ja schon einige gesehen haben) werden wie folgt dargestellt:
Um die erwartete Ausgabe eines Programms zu zeigen, wird sie manchmal hinter zwei Schrägstrichen und einem Pfeil angegeben:
console.log(factorial(8));
// → 40320
Viel Glück!
»Unter der Oberfläche der Maschine bewegt sich das Programm. Mühelos dehnt es sich aus und zieht sich zusammen. In großer Harmonie zerstreuen sich Elektronen und kommen wieder zusammen. Die Formen auf dem Monitor sind nur Wellen auf dem Wasser. Das Wesentliche bleibt unsichtbar darunter.«
– Meister Yuan-Ma, The Book of Programming
In der Welt der Computer gibt es nichts anderes als Daten. Daten können gelesen, geändert und neu erstellt werden, aber es ist nicht möglich, Dinge, die keine Daten sind, auch nur zu erwähnen. Alle diese Daten werden als lange Folgen von Bits gespeichert und sind einander dadurch grundsätzlich ähnlich.
Bits sind alle Dinge, die zwei Werte annehmen können, wobei diese Werte gewöhnlich als 0 und 1 dargestellt werden. Innerhalb des Computers nehmen sie die Form einer hohen oder niedrigen elektrischen Ladung, eines starken oder schwachen Signals bzw. eines hellen oder dunklen Punkts auf einer CD an. Jede diskrete Information kann auf eine Folge von Nullen und Einsen reduziert und damit durch Bits dargestellt werden.
Beispielsweise können wir eine Zahl wie 13 durch Bits ausdrücken. Das funktioniert genauso wie bei Dezimalzahlen, allerdings verwenden wir dazu nur zwei statt zehn verschiedene Ziffern und der Betrag wächst von rechts nach links mit jeder Stelle um den Faktor 2. Die folgende Darstellung zeigt die Bits, die die Zahl 13 bilden, mit dem Betrag der jeweiligen Stellen darunter:
0 0 0 0 1 1 0 1
128 64 32 16 8 4 2 1
Die Binärzahl lautet also 00001101. Die von 0 verschiedenen Stellen stehen darin für die Beträge 8, 4, und 1, deren Addition 13 ergibt.
Stellen Sie sich ein Meer von Bits vor. Der flüchtige Datenspeicher (Arbeitsspeicher) eines typischen modernen Computers enthält über 30 Milliarden Bits. Im nichtflüchtigen Speicher (also auf der Festplatte oder einer vergleichbaren Einrichtung) sind es gewöhnlich einige Größenordnungen mehr.
Um solche Mengen von Bits handhaben zu können, ohne die Orientierung zu verlieren, müssen wir sie daher in Blöcke aufteilen, die für einzelne Informationen stehen. In einer JavaScript-Umgebung nennen wir diese Blöcke Werte. Obwohl alle Werte aus Bits bestehen, können sie verschiedene Rollen einnehmen, wobei die Rolle eines Werts durch seinen Typ bestimmt wird. Einige Werte sind Zahlen, andere sind Texte, wieder andere Funktionen usw.
Um einen Wert zu erstellen, müssen Sie lediglich seinen Namen angeben. Das ist praktisch, denn dies bedeutet, dass es nicht nötig ist, Material für Werte heranzuschaffen oder gar dafür zu bezahlen. Sie fordern einfach den Wert an und – Simsalabim – da ist er. Natürlich werden die Werte in Wirklichkeit nicht so einfach aus dem Hut gezaubert. Jeder Wert muss irgendwo gespeichert werden, und wenn Sie gleichzeitig eine riesige Menge von Werten verwenden, geht Ihnen irgendwann der Speicher aus. Glücklicherweise ist das jedoch nur dann ein Problem, wenn Sie die Werte wirklich alle gleichzeitig benötigen. Wenn Sie einen Wert nicht brauchen, löst er sich auf und lässt seine Bits zurück, die dann als Baumaterial für die nächste Generation von Werten wiederverwendet werden können.
In diesem Kapitel lernen Sie die kleinsten Elemente von JavaScript-Programmen kennen, nämlich die einfachen Wertetypen und die Operatoren, die diese Werte bearbeiten können.
Werte, die Zahlen darstellen, sind sogenannte numerische Werte. In einem JavaScript-Programm werden sie gewöhnlich wie folgt geschrieben:
13
Wenn Sie das in ein Programm eingeben, wird innerhalb des Computerarbeitsspeichers das Bitmuster für die Zahl 13 gebildet.
Um einen numerischen Wert zu speichern, verwendet JavaScript stets eine feste Anzahl von Bits, nämlich 64. Daraus lässt sich nur eine begrenzte Anzahl von Mustern bilden, was die Menge der darstellbaren Zahlen beschränkt. Mit n Dezimalstellen lassen sich 10n Zahlen ausdrücken, mit 64 Binärstellen 264 Zahlen, also 18 Trillionen (eine 18 mit 18 Nullen). Das ist eine ganze Menge.
Computerarbeitsspeicher waren früher viel kleiner, weshalb zur Darstellung von Zahlen gewöhnlich 8 oder 16 Bits verwendet wurden. Dabei war es leicht möglich, versehentlich einen Überlauf zu verursachen, also eine Zahl zu bekommen, die nicht in die gegebene Anzahl von Bits passt. Heute haben sogar Computer für die Westentasche eine Menge Arbeitsspeicher, sodass es möglich ist, 64-Bit-Blöcke zu verwenden. Um Überläufe muss man sich nur dann Gedanken machen, wenn mit wirklich astronomischen Zahlen gearbeitet wird.
Allerdings passen nicht alle Zahlen kleiner als 18 Trillionen in den numerischen Typ von JavaScript. Da es auch möglich sein muss, negative Zahlen zu speichern, wird ein Bit zur Angabe des Vorzeichens verwendet. Ein noch größeres Problem ist die Darstellung nicht ganzzahliger Werte. Dann müssen einige der Bits dafür genutzt werden, die Position des Kommas festzuhalten. Die größte ganze Zahl, die tatsächlich gespeichert werden kann, liegt daher im Bereich von 9 Billiarden (15 Nullen), was immer noch angenehm groß ist.
Bruchzahlen werden mit einem Punkt (statt Komma) geschrieben:
9.81
Für sehr große und sehr kleine Zahlen kann auch die wissenschaftliche Schreibweise verwendet werden. Dazu schreiben Sie e (für Exponent), gefolgt vom Exponenten:
2.998e8
Berechnungen mit ganzen Zahlen (sogenannten Integer-Zahlen) kleiner als die zuvor genannten 9 Billiarden sind garantiert präzise, Berechnungen mit Bruchzahlen im Allgemeinen jedoch nicht. Ebenso wie es nicht möglich ist, π durch eine endliche Anzahl von Dezimalstellen genau darzustellen, verlieren viele Zahlen etwas von ihrer Präzision, wenn nur 64 Bits zu ihrer Speicherung zur Verfügung sehen. Das ist schade, führt in der Praxis aber nur in besonderen Situationen zu Problemen. Wichtig ist, dass Sie sich dieses Umstands bewusst sind und Bruchzahlen nur als Näherungen und nicht als exakte Werte betrachten.
Das Wichtigste, was man mit Zahlen anstellt, sind Berechnungen. Arithmetische Operationen wie Addition oder Multiplikation nehmen zwei numerische Werte entgegen und produzieren daraus eine neue Zahl. In JavaScript sieht das wie folgt aus:
100 + 4 * 11
Die Symbole + und * werden Operatoren genannt. Der erste steht für die Addition, der zweite für die Multiplikation. Ein Operator zwischen zwei Werten wird auf diese beiden angewendet und produziert einen neuen Wert.
Aber bedeutet dieses Beispiel »addiere 100 und 4 und multipliziere das Ergebnis mit 11« oder erfolgt die Multiplikation vor der Addition? Wie Sie wahrscheinlich wissen, wird die Multiplikation zuerst ausgeführt. Allerdings können Sie wie in der Mathematik die Reihenfolge ändern, indem Sie die Addition in Klammern setzen:
(100 + 4) * 11
Für die Subtraktion gibt es den Operator - und für die Division den Operator /.
Wenn keine Klammern gesetzt sind, werden Operatoren in der Reihenfolge angewendet, die durch ihren Rang bestimmt ist. In unserem Beispiel erfolgt die Multiplikation vor der Addition. Der Operator / hat den gleichen Rang wie *. Auch + und - haben den gleichen Rang. Folgen Operatoren des gleichen Rangs aufeinander, z. B. in 1 - 2 + 1, werden sie von links nach rechts ausgewertet: (1 - 2) + 1.
Machen Sie sich aber keine Sorgen über die Rangfolge von Operatoren. Im Zweifelsfall fügen Sie einfach Klammern hinzu.
Es gibt noch einen weiteren arithmetischen Operator, den Sie aber möglicherweise nicht sofort erkennen. Das Symbol % wird oft für die Restoperation verwendet. X % Y ist der Rest der Division von X durch Y. Beispielsweise ergibt 314 % 100 den Wert 14 und 144 % 12 den Wert 0. Der Restoperator hat denselben Rang wie Multiplikation und Division. Meistens wird er als Modulo bezeichnet.
In JavaScript gibt es drei besondere Werte, die zwar als Zahlen angesehen werden, sich aber nicht so verhalten.
Die ersten beiden sind Infinity und -Infinity, die für positive bzw. negative Unendlichkeit stehen. Infinity - 1 ist immer noch Infinity usw. Verlassen Sie sich aber nicht zu sehr auf Berechnungen mit unendlichen Werten. Sie sind mathematisch zweifelhaft und führen schnell zu der dritten besonderen Zahl, nämlich NaN.
NaN steht für »not a number«, also »keine Zahl«, obwohl dieser Wert tatsächlich zu den numerischen Werten gehört. Dieses Ergebnis erhalten Sie beispielsweise, wenn Sie versuchen, 0 / 0 zu berechnen (null dividiert durch null), Infinity - Infinity oder irgendeine andere numerische Operation durchführen, die kein sinnvolles Ergebnis liefert.
Den nächsten grundlegenden Datentyp bilden die Strings. Sie dienen zur Darstellung von Text. Um sie zu schreiben, wird der Inhalt in Anführungszeichen gesetzt:
`Down on the sea`
"Lie on the ocean"
'Float on the ocean'
Um Strings zu kennzeichnen, können Sie Backticks, doppelte oder einfache Anführungszeichen verwenden. Wichtig ist, dass Sie am Anfang und am Ende des Strings jeweils das gleiche Zeichen setzen.
Zwischen Anführungszeichen können Sie fast alles schreiben. JavaScript macht automatisch einen String-Wert daraus. Allerdings gibt es bei einigen Zeichen Probleme. Sie können sich vorstellen, dass es knifflig wird, wenn Sie versuchen, Anführungszeichen zwischen Anführungszeichen zu setzen. Zeilenumbrüche (also die Zeichen, die Sie erhalten, wenn Sie die Eingabetaste drücken) lassen sich nur dann ohne Maskierung eingeben, wenn der String in Backticks (`) eingeschlossen ist.
Um auch solche problematischen Zeichen in Strings einschließen zu können, wird die folgende Schreibweise verwendet: Tritt innerhalb von Text in Anführungszeichen ein Backslash (umgekehrter Schrägstrich, \) auf, dann bedeutet dies, dass das darauffolgende Zeichen eine besondere Bedeutung hat. Auf diese Weise wird das Zeichen maskiert. Ein Anführungszeichen mit einem vorausgehenden Backslash beendet den String nicht, sondern ist ein Teil von ihm. Steht das Zeichen n hinter einem Backslash, wird es als Zeilenumbruch gedeutet, und ein t hinter einem Backslash steht für den Tabulator. Betrachten Sie als Beispiel den folgenden String:
"This is the first line\nAnd this is the second"
Der enthaltene Text lautet:
This is the first line
And this is the second
Es kann natürlich auch vorkommen, dass ein Backslash in einem String als Backslash wiedergegeben werden soll, anstatt eine besondere Funktion auszuüben. Wenn zwei Backslashes aufeinander folgen, maskiert der erste den zweiten, sodass im resultierenden String-Wert nur der zweite übrigbleibt. Um beispielsweise den String "A newline character is written like "\n"." auszudrücken, können Sie Folgendes schreiben:
"A newline character is written like \"\\n\"."
Um innerhalb eines Computers existieren zu können, müssen auch Strings als Folge von Bits modelliert werden. JavaScript zieht dazu den Unicode-Standard heran. Er weist Zahlen praktisch jedem Zeichen zu, das Sie jemals brauchen könnten, darunter auch griechischen, arabischen, japanischen und armenischen Buchstaben usw. Wenn es für jedes Zeichen eine Zahl gibt, kann ein String als Folge von Zahlen ausgedrückt werden.
Genau das ist es, was JavaScript macht. Es gibt jedoch ein Problem: In der JavaScript-Darstellung werden 16 Bits pro String-Element genutzt, womit sich 216 verschiedene Zeichen beschreiben lassen. Unicode aber definiert noch mehr Zeichen, zurzeit etwa doppelt so viele. Daher nehmen manche Zeichen, etwa Emojis, in JavaScript zwei Zeichenpositionen ein. Auf Strings und Zeichencodes werden wir auf S. 64 zurückkommen.
Strings können nicht dividiert, multipliziert oder subtrahiert werden, aber es ist möglich, den Operator + auf sie anzuwenden. In diesem Fall dient er nicht zur Addition, sondern zur Verkettung – er verbindet die beiden Strings. Die folgende Zeile produziert den String "Verkettung":
"Ver" + "ket" + "t" + "ung"
Es gibt eine Reihe von zugehörigen Funktionen (Methoden), um noch andere Operationen an String-Werten auszuführen. Mehr über Methoden erfahren Sie auf S. 64.
Strings in einfachen oder doppelten Anführungszeichen verhalten sich sehr ähnlich. Der einzige Unterschied besteht darin, welche Art von Anführungszeichen Sie in ihnen maskieren müssen. Strings in Backticks dagegen, die gewöhnlich als Template-Literale bezeichnet werden, leisten noch mehr. Sie können nicht nur mehrere Zeilen überspannen, sondern auch andere Werte enthalten:
`half of 100 is ${100 / 2}`
Wenn Sie in einem Template-Literal etwas in ${} schreiben, wird das Ergebnis berechnet, in einen String umgewandelt und an dieser Stelle eingeführt. In dem Beispiel ergibt sich half of 100 is 50.
Nicht alle Operatoren sind Symbole. Einige werden auch als Wörter geschrieben. Ein Beispiel dafür ist der Operator typeof. Er erzeugt einen String-Wert mit dem Namen des Typs, den der übergebene Wert hat:
console.log(typeof 4.5)
// → number
console.log(typeof "x")
// → string
In unserem Beispielcode verwenden wir console.log um anzugeben, dass wir das Ergebnis einer Auswertung sehen wollen. Mehr darüber erfahren Sie im nächsten Kapitel.
Alle anderen bisher vorgestellten Operatoren nehmen zwei Werte entgegen, typeof dagegen nur einen. Operatoren, die zwei Werte verwenden, werden als binäre Operatoren bezeichnet, Operatoren mit nur einem Eingangswert als unäre. Der Minusoperator kann sowohl als binärer als auch als unärer Operator eingesetzt werden:
console.log(- (10 - 2))
// → -8
Oft ist es praktisch, einen Wert zur Verfügung zu haben, der nur zwei mögliche Formen annehmen kann, etwa »ja« und »nein« oder »ein« und »aus«. Für diesen Zweck gibt es in JavaScript den booleschen Datentyp mit nur zwei Werten, nämlich »wahr« und »falsch«, geschrieben als true und false.
Eine Möglichkeit, um boolesche Werte zu erzeugen, sieht wie folgt aus:
console.log(3 > 2)
// → true
console.log(3 < 2)
// → false
Die Zeichen > und < sind die herkömmlichen Symbole für »ist größer als« bzw. »ist kleiner als«. Die Anwendung dieser binären Operatoren ergibt einen booleschen Wert, der anzeigt, ob die Vergleiche wahr sind oder nicht.
Auch Strings lassen sich auf diese Weise vergleichen:
console.log("Aardvark" < "Zoroaster")
// → true
Die Sortierung von Strings ist grob gesehen alphabetisch, allerdings weicht sie von der Reihenfolge ab, wie man sie aus einem Wörterbuch kennt: Großbuchstaben sind immer »kleiner« als Kleinbuchstaben (es gilt also "Z" < "a") und die Sortierung schließt auch Zeichen ein, die keine Buchstaben sind (wie !, - usw.). Beim String-Vergleich geht JavaScript die Zeichen von links nach rechts durch und vergleicht ihre Unicode-Codes einen nach dem anderen.
Es gibt nur einen Wert in JavaScript, der nicht gleich sich selbst ist, und das ist NaN (»not a number«):
NaN kennzeichnet das Ergebnis einer unsinnigen Berechnung und ist daher nicht gleich dem Ergebnis einer anderen unsinnigen Berechnung.
Auf die booleschen Werte selbst können ebenfalls Operationen angewendet werden. Dazu gibt es in JavaScript die drei logischen Operatoren und, oder und nicht. Damit lassen sich Schlussfolgerungen über boolesche Werte anstellen.
Der Operator && steht für das logische und. Es handelt sich bei ihm um einen binären Operator, und das Ergebnis lautet nur dann true, wenn beide gegebenen Werte wahr sind:
console.log(true && false)
// → false
console.log(true && true)
// → true
Der Operator ||, das logische oder, ergibt true, wenn wenigstens einer der beiden gegebenen Werte wahr ist:
console.log(false || true)
// → true
console.log(false || false)
// → false
Nicht wird als Ausrufezeichen geschrieben. Dieser unäre Operator kehrt den gegebenen Wahrheitswert um: !true ergibt false, !false ergibt true.
Der letzte logische Operator, den ich hier besprechen möchte, ist weder unär noch binär, sondern ternär, d. h., er nimmt drei Werte entgegen. Geschrieben wird er wie folgt mit einem Fragezeichen und einem Doppelpunkt:
console.log(true ? 1 : 2);
// → 1
console.log(false ? 1 : 2);
// → 2
Dieser Operator wird als Bedingungsoperator bezeichnet (manchmal auch nur als »der ternäre Operator«, da er der einzige dieser Art in JavaScript ist). Der Wert auf der linken Seite des Fragezeichens bestimmt, welcher der beiden anderen Werte ausgegeben werden soll. Ist er wahr, so wird der mittlere genommen, ist er falsch, der rechte.
Um die Abwesenheit eines sinnvollen Werts zu kennzeichnen, werden die beiden besonderen Werte null und undefined verwendet. Es handelt sich bei ihnen zwar um Werte, allerdings haben sie keinen Informationsgehalt.
Viele Operationen, die keinen sinnvollen Wert produzieren (einige davon werden Sie später noch kennenlernen), geben undefined zurück, da sie schließlich irgendeinen Wert zurückgeben müssen.
Der Bedeutungsunterschied zwischen undefined und null ist eher ein Missgriff im Design von JavaScript und spielt meistens keine Rolle. Wenn Sie mit diesen Werten zu tun haben, sollten Sie sie als größtenteils austauschbar betrachten.
In der Einleitung habe ich schon erwähnt, dass JavaScript alles versucht, um möglichst jedes Programm zu akzeptieren, das Sie übergeben, auch wenn dieses Programm merkwürdige Dinge tut. Die folgenden Beispielausdrücke machen das schön deutlich:
Wird ein Operator auf einen Wert eines unpassenden Typs angewendet, wandelt JavaScript diesen Wert stillschweigend in den erforderlichen Typ um. Die Regeln dafür entsprechend aber nicht immer dem, was Sie beabsichtigen oder erwarten. Dieser Vorgang wird implizite Typumwandlung genannt. Aus null im ersten Ausdruck wird 0. Der String "5" im zweiten Ausdruck wird in die Zahl 5 umgewandelt. Im dritten Ausdruck dagegen wird erst versucht, + für eine String-Verkettung und nicht für eine Addition zu verwenden, weshalb die Zahl 1 hier in den String "1" umgewandelt wird.
Wenn Werte, die nicht offensichtlich Zahlen entsprechen (wie "five" oder "undefined"), dennoch in Zahlen umgewandelt werden, erhalten Sie den Wert NaN. Arithmetische Operationen mit NaN ergeben immer wieder NaN. Wenn Sie diesen Wert an unerwarteter Stelle erhalten, sollten Sie daher nach versehentlichen Typumwandlungen Ausschau halten.
Ich rate dazu, diese aus drei Zeichen bestehenden Operatoren als Schutzvorkehrung zu nutzen, um unbeabsichtigte Typumwandlungen zu verhindern. Wenn Sie aber sicher sind, dass auf beiden Seiten Werte desselben Typs stehen, können Sie problemlos die kürzeren Operatoren verwenden.
Die logischen Operatoren && und || handhaben Werte unterschiedlichen Typs auf eigenartige Weise. Sie konvertieren den Wert auf der linken Seite in einen booleschen Typ, um zu entscheiden, was sie tun sollen, aber je nach Operator und dem Ergebnis dieser Umwandlung geben sie entweder den ursprünglichen linken oder den rechten Wert zurück.
Beispielsweise gibt der Operator || den Wert auf der linken Seite zurück, wenn dieser in true umgewandelt werden kann, und sonst den Wert auf der rechten Seite. Bei booleschen Werten führt das zu dem zu erwartenden Ergebnis, und Werte anderer Typen werden in ähnlichem Sinne behandelt:
console.log(null || "user")
// → user
console.log("Agnes" || "user")
// → Agnes
Diese Vorgehensweise können wir als eine Möglichkeit nutzen, um auf einen Standardwert zurückzugreifen. Besteht die Gefahr, dass ein Wert leer ist, können Sie hinter || einen Ersatzwert angeben. Falls der ursprüngliche Wert in false konvertiert wird, erhalten Sie dann den Ersatzwert. Nach den Regeln für die Umwandlung von Strings und Zahlen in boolesche Werte werden 0, NaN und der leere String ("") als false aufgefasst, alle anderen als true. Das Ergebnis von 0 || -1 lautet daher -1, und !! || "!?" wird zu "!?" ausgewertet.
Der Operator && geht ähnlich vor, aber anderes herum. Kann der Wert auf der linken Seite in false umgewandelt werden, so wird dieser Wert zurückgegeben, anderenfalls der Wert auf der rechten Seite.
Eine weitere wichtige Eigenschaft dieser beiden Operatoren besteht darin, dass der Teil auf ihrer rechten Seite nur dann ausgewertet wird, wenn es notwendig ist. So spielt es bei true || X keine Rolle, was X ist – selbst wenn es ein Teil eines Programms ist, der irgendetwas wirklich Fürchterliches tut. Das Ergebnis lautet in jedem Fall true, und X wird niemals ausgewertet. Das Gleiche gilt auch für false && X, was stets false ist, weshalb X ignoriert wird. Dies wird als kurzgeschlossene Auswertung bezeichnet.
Der Bedingungsoperator verhält sich ähnlich. Von den beiden hinteren Werten wird nur derjenige ausgewertet, der ausgewählt wird.
In diesem Kapitel haben wir uns vier Typen von JavaScript-Werten angesehen: Zahlen, Strings, boolesche Werte und nichtdefinierte Werte.
Um diese Werte zu erstellen, geben Sie ihre Bezeichnung (true, null) oder ihren Wert (13, "abc") an. Mithilfe von Operatoren können Sie Werte kombinieren und transformieren. Wir haben Binäroperatoren für arithmetische Berechnungen (+, -, *, / und %), für die String-Verkettung (+) und für Vergleiche (, !=, , !==, <, >, <=, >=), logische binäre Operatoren (&&, ||), verschiedene unäre Operatoren (- zur Negation einer Zahl, ! zur Negation eines logischen Werts und typeof, um den Typ eines Werts zu ermitteln) sowie einen ternären Operator (?:) kennengelernt, der auf der Grundlage eines Wertes zwischen zwei anderen auswählt.
Mit diesen Kenntnissen können Sie JavaScript wie einen Taschenrechner verwenden, aber noch nicht viel mehr tun. Im nächsten Kapitel beginnen wir, diese Ausdrücke zu einfachen Programmen zu kombinieren.
»Mein Herz glüht hellrot unter meiner dünnen, durchscheinenden Haut, und sie müssen mir 10 cm3 JavaScript injizieren, um mich zurückzuholen. (Ich reagiere gut auf Giftstoffe im Blut.) Mann, dieser Stoff haut dir echt die Pfirsiche aus den Kiemen!«
– _why, Why’s (Poignant) Guide to Ruby
In diesem Kapitel beginnen wir damit, Aufgaben zu erledigen, die tatsächlich die Bezeichnung Programmierung verdienen. Wir erweitern unsere Kenntnisse der Sprache JavaScript über die Nomen und Satzfragmente hinaus, die wir bereits kennengelernt haben, sodass wir sinnvolle Prosa schreiben können.
In Kapitel 1 haben wir Werte erstellt und Operatoren darauf angewendet, um neue Werte zu erhalten. Werte auf diese Weise zu erstellen, ist ein wesentlicher Bestandteil aller JavaScript-Programme. Um nützlich zu sein, muss dieser Bestandteil aber in eine umfassende Struktur eingebettet werden. Das ist es, womit wir uns als Nächstes beschäftigen werden.
Ein Codefragment, das einen Wert produziert, wird als Ausdruck bezeichnet. Jeder explizit niedergeschriebene Wert (z. B. 22 oder "psychoanalysis") ist ein Ausdruck. Steht ein Ausdruck in Klammern, so ist dies ebenfalls ein Ausdruck. Wird ein binärer Operator auf zwei Ausdrücke oder ein unärer Operator auf einen Ausdruck angewendet, ist auch das ein Ausdruck.
Das macht die Schönheit einer sprachgestützten Schnittstelle deutlich: Ausdrücke können andere Ausdrücke auf eine ähnliche Weise enthalten, wie Teilsätze in menschlichen Sprachen verschachtelt werden. Auch hier kann jeder Teilsatz wiederum seine eigenen Teilsätze enthalten usw. Damit können wir Ausdrücke erstellen, die beliebig komplizierte Berechnungen beschreiben.
Wenn ein Ausdruck einem Teilsatz entspricht, so entspricht eine JavaScript-Anweisung einem vollständigen Satz. Ein Programm wiederum ist eine Folge von Anweisungen.
Die einfachste Art von Anweisung ist ein Ausdruck mit einem abschließenden Semikolon. Das Folgende ist bereits ein Programm:
1;
!false;
Allerdings ist dies ein völlig nutzloses Programm. Ein Ausdruck braucht lediglich einen Wert hervorzurufen, der dann vom umgebenden Code genutzt werden kann. Eine Anweisung aber steht für sich allein. Daher ist sie nur dann sinnvoll, wenn sie sich auf die Welt auswirkt. Beispielsweise kann sie etwas auf dem Bildschirm darstellen, was sich als eine Änderung der Welt sehen lässt. Sie kann auch den internen Zustand des Computers auf eine Weise ändern, die sich auf nachfolgende Anweisungen auswirkt. Solche Änderungen werden als Nebenwirkungen bezeichnet (meistens leider jedoch aufgrund einer wortwörtlichen Fehlübersetzung aus dem Englischen als Seiteneffekte). Die Anweisungen im vorigen Beispiel dagegen produzieren nur die Werte 1 und true und verwerfen sie dann sofort wieder, ohne eine bleibenden Eindruck in der Welt zu hinterlassen. Wenn Sie dieses Programm ausführen, geschieht nichts, was man beobachten könnte.
In manchen Fällen erlaubt Ihnen JavaScript, auf das Semikolon am Ende einer Anweisung zu verzichten, in anderen Fällen dagegen muss es unbedingt vorhanden sein, da die nächste Zeile sonst als ein weiterer Bestandteil der Anweisung aufgefasst wird. Die Regeln dafür, wann das Semikolon gefahrlos weggelassen werden kann, sind ziemlich kompliziert und fehleranfällig. In diesem Buch erhält jede Anweisung ein Semikolon. Ich rate Ihnen, genauso vorzugehen, zumindest so lange, bis Sie mehr über die Feinheiten fehlender Semikolons gelernt haben.
Wie erhält ein Programm seinen internen Status aufrecht? Wie merkt es sich etwas? Wir wissen bereits, wie wir aus alten Werten neue produzieren, aber dabei werden die alten Werte nicht geändert und die neuen müssen sofort verwendet werden, da sie sich sonst wieder in Wohlgefallen auflösen. Um Werte zu erfassen und festzuhalten, gibt es in JavaScript Bindungen oder Variablen:
Im vorstehenden Beispiel wird die Bindung caught erstellt und dazu genutzt, die Zahl festzuhalten, die durch die Multiplikation von 5 mit 5 produziert wird.
Nachdem eine Bindung definiert wurde, kann ihr Name als Ausdruck verwendet werden. Der Wert dieses Ausdrucks ist der Wert, den die Bindung zurzeit festhält. Betrachten Sie dazu das folgende Beispiel:
Stellen Sie sich Bindungen eher wie Tentakel und nicht wie Kisten vor. Sie enthalten keine Werte, sondern halten sie fest. Zwei Bindungen können auch auf denselben Wert verweisen. Ein Programm kann nur auf die Werte zugreifen, zu denen es noch einen Verweis hat. Wenn es sich an etwas erinnern muss, lässt es einen Tentakel wachsen, um es festzuhalten, oder greift mit einem bereits vorhandenen Tentakel danach.
Sehen wir uns dazu ein weiteres Beispiel an. Um sich zu merken, wie viele Euro Luigi Ihnen noch schuldet, erstellen Sie eine Bindung. Wenn er Ihnen 35 Euro zurückzahlt, geben Sie dieser Bindung einen neuen Wert:
Falls Sie eine Bindung definieren, ohne ihr einen Wert zu geben, hat der Tentakel nichts, was er festhalten kann, sondern endet in der Luft. Wenn Sie dann nach dem Wert dieser leeren Bindung fragen, erhalten Sie den Wert undefined.
Mit einer einzigen let-Anweisung können Sie mehrere Bindungen definieren, wobei die einzelnen Bindungen durch Kommata zu trennen sind:
Auch mit den Wörtern var und const lassen sich ähnlich wie mit let Bindungen erstellen:
Die erste Möglichkeit, var (kurz für »Variable«), ist die Art und Weise, in der Bindungen in JavaScript vor 2015 deklariert wurden. Auf die genauen Unterschiede zwischen var und let werde ich im nächsten Kapitel eingehen. Merken Sie sich zunächst nur, dass var größtenteils das Gleiche macht wie let. Wir werden es in diesem Buch allerdings selten verwenden, da es einige verwirrende Eigenschaften hat.
Das Wort const definiert eine konstante Bindung, die während ihrer gesamten Existenz auf denselben Wert zeigt. Das ist praktisch, um einem Wert einen Namen zu geben, sodass Sie später leichter darauf verweisen können.
Als Namen von Bindungen können Sie beliebige Wörter verwenden. Die Namen können auch Ziffern enthalten – so ist etwa catch22 ein gültiger Name –, dürfen aber nicht mit einer Ziffer beginnen. Ebenfalls erlaubt sind Dollarzeichen und Unterstriche, aber keine anderen Satz- oder Sonderzeichen.
Wörter wie let, die eine besondere Bedeutung haben, sind Schlüsselwörter und dürfen nicht als Namen für Bindungen verwendet werden. Es gibt auch eine Reihe von Wörtern, die für die Verwendung in zukünftigen Versionen von JavaScript »reserviert« sind und ebenfalls nicht als mögliche Bindungsnamen bereitstehen. Die vollständige Liste der Schlüsselwörter ist ziemlich lang:
break case catch class const continue debugger default
delete do else enum export extends false finally for
function if implements import interface in instanceof let
new package private protected public return static super
switch this throw true try typeof var void while with yield
Machen Sie sich aber nicht die Mühe, diese Liste auswendig zu lernen! Wenn der Versuch, eine Bindung zu erstellen, zu einem unerwarteten Syntaxfehler führt, schauen Sie nach, ob Sie ein reserviertes Wort verwendet haben.
Die Gesamtheit der Bindungen und ihrer Werte, die zu einem gegebenen Zeitpunkt vorhanden sind, wird als Umgebung bezeichnet. Auch beim Start eines Programms ist die Umgebung nicht leer, denn sie enthält immer die Bindungen, die zum Sprachstandard gehören, und Bindungen zur Interaktion mit dem umgebenden System. In einem Browser gibt es beispielsweise Funktionen zur Interaktion mit der gerade geladenen Website und zum Erfassen der Maus- und Tastatureingaben.
Viele Werte, die in der Standardumgebung zur Verfügung stehen, haben den Typ von Funktionen. Eine Funktion ist ein Programmteil, der in einen Wert eingeschlossen ist. Solche Werte können angewendet werden, um das eingeschlossene Programm auszuführen. Beispielsweise hält in einer Browserumgebung die Bindung prompt eine Funktion fest, die ein kleines Dialogfeld anzeigt, um den Benutzer zu einer Eingabe aufzufordern. Diese Bindung wird wie folgt verwendet:
prompt("Enter passcode");
Bei der Ausführung einer Funktion wird davon gesprochen, dass sie aufgerufen oder angewendet wird. Um eine Funktion aufzurufen, können Sie ein Paar Klammern hinter einen Ausdruck setzen, der einen Funktionswert produziert. Gewöhnlich verwenden Sie dazu den Namen der Bindung, die die Funktion festhält. Die Werte in den Klammern werden dem Programm in der Funktion übergeben. In dem vorigen Beispiel nutzt die Funktion prompt den übergebenen String als den Text, den sie in dem Dialogfeld anzeigt. An Funktionen übergebene Werte werden als Argumente bezeichnet. Die Anzahl und der Typ der Argumente sind von Funktion zu Funktion unterschiedlich.
Die Funktion prompt wird in der modernen Webprogrammierung kaum verwendet, weil Sie dabei keine Kontrolle darüber haben, wie das resultierende Dialogfeld aussieht. Zum Herumspielen und Ausprobieren allerdings ist sie ganz nützlich.
In den Beispielen habe ich console.log verwendet, um Werte auszugeben. Die meisten JavaScript-Systeme (darunter alle modernen Webbrowser und Node.js) weisen eine Funktion namens console.log auf, die ihre Argumente an ein Textausgabegerät schicken. In Browsern landet diese Ausgabe in der JavaScript-Konsole. Dieser Teil der Browseroberfläche ist normalerweise ausgeblendet, kann in den meisten Browsern aber mit bzw. auf dem Mac mit geöffnet werden. Wenn das nicht funktioniert, suchen Sie im Menü nach einem Eintrag, der »Entwicklertools« o. ä. heißt.
Bindungsnamen dürfen keine Punkte enthalten, aber in console.log ist einer vorhanden. Das liegt daran, dass es sich bei console.log nicht um eine einfache Bindung handelt, sondern um einen Ausdruck, der die Eigenschaft log von dem Wert abruft, der von der Bindung console festgehalten wird. Was das genau bedeutet, erfahren Sie im Abschnitt »Eigenschaften« auf S. 63.
Ein Dialogfeld einzublenden oder Text auf den Bildschirm zu schreiben, ist lediglich ein Seiteneffekt. Viele Funktionen sind gerade wegen ihrer Seiteneffekte nützlich. Funktionen können jedoch auch Werte produzieren. In diesem Fall müssen sie keine Seiteneffekte haben, um nützlich zu sein. Beispielsweise nimmt die Funktion Math.max eine beliebige Anzahl von Argumenten entgegen und gibt das größte davon zurück:
console.log(Math.max(2, 4));
// → 4
In diesem Fall spricht man davon, dass die Funktion einen Wert zurückgibt. Alles, was einen Wert produziert, wird in JavaScript als Ausdruck angesehen. Das wiederum bedeutet, dass Funktionsaufrufe innerhalb umfangreicherer Ausdrücke verwendet werden können. Im folgenden Beispiel wird Math.min, das Gegenteil von Math.max, innerhalb eines Additionsausdrucks verwendet:
console.log(Math.min(2, 4) + 100);
// → 102
Im nächsten Kapitel erfahren Sie, wie Sie Ihre eigenen Funktionen schreiben.
Wenn ein Programm mehrere Anweisungen enthält, werden diese von vorn nach hinten ausgeführt. Das folgende Beispielprogramm hat zwei Anweisungen, von denen die erste zur Eingabe einer Zahl auffordert und die zweite, die danach ausgeführt wird, das Quadrat dieser Zahl anzeigt:
Die Funktion Number wandelt einen Wert in eine Zahl um. Diese Konvertierung ist erforderlich, da das Ergebnis von prompt ein String-Wert ist, wir aber eine Zahl brauchen. Es gibt ähnliche Funktionen wie String und Boolean, die Werte in die entsprechenden Typen umwandeln.
Dieser geradlinige Programmablauf lässt sich durch das folgende, ziemlich triviale Diagramm darstellen: