Entdecken Sie Millionen von E-Books, Hörbüchern und vieles mehr mit einer kostenlosen Testversion

Nur $11.99/Monat nach der Testphase. Jederzeit kündbar.

JavaScript – Das Handbuch für die Praxis: Meistern Sie die beliebte Sprache für Web und Node.js
JavaScript – Das Handbuch für die Praxis: Meistern Sie die beliebte Sprache für Web und Node.js
JavaScript – Das Handbuch für die Praxis: Meistern Sie die beliebte Sprache für Web und Node.js
eBook1.474 Seiten14 Stunden

JavaScript – Das Handbuch für die Praxis: Meistern Sie die beliebte Sprache für Web und Node.js

Bewertung: 0 von 5 Sternen

()

Vorschau lesen

Über dieses E-Book

Seit 25 Jahren das begleitende Grundlagenwerk zu JavaScript


- Durchgehend überarbeiteter Bestseller in der 7. Auflage

- Deckt die Version ES2020 inkl. Tools/Extensions & Node.js ab
<

- Vermittelt umfassendes und tiefgehendes JavaScript-Know-how

JavaScript ist die Programmiersprache des Webs und der Bestseller "JavaScript: Das Handbuch für die Praxis" seit fast 25 Jahren und über sieben Auflagen ein geschätztes Grundlagenwerk für diese Sprache.
Umfassend und detailliert dokumentiert Flanagan die wichtigsten client- und serverseitigen APIs. Die 7. Auflage wurde vollständig aktualisiert und deckt die Version 2020 von JavaScript ab. Freuen Sie sich auf spannende und inspirierende Codebeispiele und neue Kapitel über Klassen, Module, Iteratoren, Generatoren, Promises und async/await.
Das Buch wendet sich an JavaScript-Neulinge mit Programmierkenntnissen sowie JavaScript-Programmierende, die ihr Verständnis vertiefen wollen. Die Zeit, die Sie in die Lektüre investieren, wird sich durch eine deutlich gesteigerte Produktivität garantiert rasch auszahlen.
SpracheDeutsch
HerausgeberO'Reilly
Erscheinungsdatum22. Apr. 2021
ISBN9783960104926
JavaScript – Das Handbuch für die Praxis: Meistern Sie die beliebte Sprache für Web und Node.js

Mehr von David Flanagan lesen

Ähnliche Autoren

Ähnlich wie JavaScript – Das Handbuch für die Praxis

Ähnliche E-Books

Programmieren für Sie

Mehr anzeigen

Ähnliche Artikel

Rezensionen für JavaScript – Das Handbuch für die Praxis

Bewertung: 0 von 5 Sternen
0 Bewertungen

0 Bewertungen0 Rezensionen

Wie hat es Ihnen gefallen?

Zum Bewerten, tippen

Die Rezension muss mindestens 10 Wörter umfassen

    Buchvorschau

    JavaScript – Das Handbuch für die Praxis - David Flanagan

    KAPITEL 1

    Einführung in JavaScript

    JavaScript ist die Programmiersprache des Webs. Der weitaus größte Teil moderner Websites nutzt JavaScript, und alle modernen Webbrowser – auf Desktops, Tablets und Smartphones – besitzen JavaScript-Interpreter, was JavaScript zur am häufigsten eingesetzten Programmiersprache überhaupt macht. In den letzten zehn Jahren hat Node.js die JavaScript-Programmierung auch außerhalb von Webbrowsern ermöglicht, und der dramatische Erfolg von Node hat dazu geführt, dass JavaScript nun auch die unter Softwareentwicklern am häufigsten verwendete Programmiersprache ist. Egal ob Sie bei null anfangen oder JavaScript bereits professionell einsetzen, dieses Buch wird Ihnen dabei helfen, diese Sprache zu beherrschen.

    Wenn Sie schon mit anderen Programmiersprachen vertraut sind, ist es vielleicht hilfreich, zu wissen, dass es sich bei JavaScript um eine dynamische, interpretierte Hochsprache handelt, die für objektorientierte wie auch funktionale Programmierstile sehr gut geeignet ist. Die Variablen von JavaScript sind untypisiert. Ihre Syntax basiert lose auf Java, aber die Sprachen sind ansonsten nicht miteinander verwandt. JavaScript leitet seine erstklassigen Funktionen von Scheme und seine prototypenbasierte Vererbung von der wenig bekannten Sprache Self ab. Sie müssen aber diese Sprachen weder kennen noch auch nur mit den Begriffen vertraut sein, um dieses Buch verwenden und JavaScript erlernen zu können.

    Der Name »JavaScript« ist leicht irreführend. Abgesehen von einer oberflächlichen Ähnlichkeit der Syntax unterscheidet sich JavaScript komplett von Java. Darüber hinaus ist JavaScript längst über seine Wurzeln als Skriptsprache hinausgewachsen und zu einer robusten und effizienten Allzwecksprache geworden, die sich für ernsthaftes Softwareengineering und für Projekte mit riesigen Codebasen eignet.

    Damit man eine Sprache nutzen kann, muss sie eine Plattform- bzw. Standardbibliothek besitzen, um zum Beispiel die Ein- und Ausgabe zu ermöglichen. Der Sprachkern von JavaScript legt eine minimale API für den Umgang mit Zahlen, Text, Arrays, Sets, Maps usw. fest, besitzt aber keine Ein- und Ausgabefunktionalität. Diese (und fortgeschrittenere Features der Bereiche Netzwerk, Speicher und Grafik) liegen ganz in der Verantwortung der Hostumgebung, in die JavaScript eingebettet ist.

    JavaScript: Namen, Versionen und Modi

    JavaScript wurde in den frühen Tagen des Webs bei Netscape entwickelt, und die Bezeichnung JavaScript selbst ist ein von Sun Microsystems (jetzt Oracle) lizenziertes Warenzeichen, das zur Beschreibung der Implementierung der Sprache durch Netscape (jetzt Mozilla) verwendet wird. Netscape hatte die Sprache zur Standardisierung bei der ECMA eingereicht – der European Computer Manufacturers Association –, und aufgrund von Markenrechtsproblemen erhielt die standardisierte Version der Sprache den sperrigen Namen »ECMAScript«. In der Praxis spricht aber eigentlich jeder von JavaScript. In diesem Buch werden der Name ECMAScript und die Abkürzung ES benutzt, um speziell auf den Sprachstandard und auf bestimmte Versionen dieses Standards hinzuweisen.

    In den 2010er-Jahren wurde von allen Webbrowsern überwiegend Version 5 des ECMAScript-Standards unterstützt. Deshalb wird in diesem Buch ES5 als die Kompatibilitäts-Baseline betrachtet, sodass frühere Versionen der Sprache nicht behandelt werden. ES6 wurde 2015 veröffentlicht und fügte wichtige neue Funktionen – darunter die Klassen- und Modulsyntax – hinzu, die JavaScript von einer Skriptsprache in eine ernst zu nehmende, allgemein einsetzbare Sprache verwandelten, die sich auch für die Softwareentwicklung in großem Maßstab eignet. Seit ES6 wird die ECMAScript-Spezifikation jährlich überarbeitet, und die Versionen der Sprache – ES2016, ES2017, ES2018, ES2019 und ES2020 usw. – werden jetzt nach dem Jahr der Veröffentlichung benannt.

    Während der Entwicklung von JavaScript versuchten die Sprachdesigner, Fehler in den frühen Versionen (vor ES5) zu korrigieren. Um die Abwärtskompatibilität aufrechtzuerhalten, ist es nicht möglich, ältere Sprachmerkmale (sogenannte Legacy-Features) zu entfernen, egal wie mangelhaft sie sind. Aber in ES5 und späteren Versionen können Programme in den Strict Mode – den strikten oder strict-Modus – von JavaScript wechseln, in dem eine Reihe von frühen Sprachfehlern korrigiert wurde. Um diesen Modus zu aktivieren, benutzt man die »use strict«-Anweisung, die in 5.6.3 besprochen wird. Dieser Abschnitt fasst auch die Unterschiede zwischen Legacy-JavaScript und JavaScript im strict-Modus zusammen. In ES6 und später aktiviert die Verwendung neuer Sprachfunktionen oft implizit den strict-Modus. Wenn Sie beispielsweise das ES6-Schlüsselwort class verwenden oder ein ES6-Modul erstellen, ist der gesamte Code innerhalb der Klasse oder des Moduls automatisch »strict«, und die alten, mangelhaften Funktionen sind in diesen Kontexten nicht verfügbar. In diesem Buch behandle ich auch die Legacy-Features von JavaScript, weise aber darauf hin, dass diese im strict-Modus nicht verfügbar sind.

    Die ursprüngliche Hostumgebung für JavaScript war ein Webbrowser, und das ist immer noch die am häufigsten verwendete Ausführungsumgebung für JavaScript-Code. In einer Webbrowserumgebung kann JavaScript-Code Input durch Maus und Tastatur des Benutzers sowie durch HTTP-Anfragen erhalten, dem Nutzer aber auch per HTML und CSS Ausgaben anzeigen.

    Seit 2010 ist eine weitere Hostumgebung für JavaScript-Code verfügbar. Anstatt JavaScript auf die Arbeit mit den APIs zu beschränken, die von einem Webbrowser bereitgestellt werden, gibt Node JavaScript Zugriff auf das gesamte Betriebssystem, sodass JavaScript-Programme Dateien lesen und schreiben, Daten über das Netzwerk senden und empfangen sowie HTTP-Anfragen stellen und bedienen können. Node ist eine beliebte Wahl zur Implementierung von Webservern und außerdem ein bequemes Werkzeug zum Schreiben einfacher Hilfsskripte als Alternative zu Shell-Skripten.

    Der größte Teil dieses Buchs konzentriert sich auf die Programmiersprache JavaScript selbst, Kapitel 11 dokumentiert die JavaScript-Standardbibliothek, Kapitel 15 und 16 stellen Webbrowser sowie Node als Hostumgebungen vor.

    In diesem Buch werden zunächst die Grundlagen beschrieben, um dann darauf aufbauend zu fortgeschritteneren Abstraktionen auf höherer Ebene überzugehen. Die Kapitel sind dazu gedacht, mehr oder weniger der Reihe nach gelesen zu werden. Aber das Erlernen einer neuen Programmiersprache ist kein linearer Prozess und ebenso wenig das Beschreiben einer Sprache: Jedes Sprachfeature hängt mit anderen Merkmalen zusammen, und dieses Buch ist mit Querverweisen gespickt – manchmal auf zurückliegende Kapitel, manchmal auf Material, das Sie noch nicht gelesen haben. Dieses Einführungskapitel gibt Ihnen einen ersten Überblick über die Sprache und führt in die wichtigsten Merkmale ein, die das Verständnis einer detaillierteren Behandlung in den folgenden Kapiteln erleichtern werden. Falls Sie bereits JavaScript programmieren, können Sie dieses Kapitel wahrscheinlich überspringen. (Obwohl Sie sicher gern Beispiel 1-1 am Ende des Kapitels lesen möchten, bevor Sie zu einem anderen Kapitel übergehen.)

    1.1JavaScript erkunden

    Wenn man eine neue Programmiersprache lernt, ist es wichtig, die Beispiele auszuprobieren, sie dann selbst zu modifizieren und erneut auszuprobieren, um das erworbene Verständnis der Sprache zu testen. Dazu benötigen Sie einen JavaScript-Interpreter.

    Am einfachsten lassen sich ein paar Zeilen JavaScript ausprobieren, indem man – mit F12 bzw. Strg+Umschalt+I in Windows- bzw. Befehlstaste+Optionstaste+I in MacUmgebungen – die Entwicklertools in einem Webbrowser öffnet und auf die Registerkarte Konsole wechselt. Sie können dann in der Eingabeaufforderung Code eingeben und während der Eingabe die Ergebnisse sehen. Die Entwicklerwerkzeuge erscheinen oft als Fenster am unteren oder rechten Rand des Browserfensters, aber Sie können sie normalerweise als separate Fenster abkoppeln (wie in Abbildung 1-1 gezeigt), was oft recht bequem ist.

    Abbildung 1-1: Die JavaScript-Konsole in den Entwicklertools von Firefox

    Um JavaScript-Code auszuprobieren, können Sie auch Node von https://nodejs.org herunterladen und installieren. Sobald Node auf Ihrem System eingerichtet ist, öffnen Sie einfach ein Terminalfenster und geben node ein, um eine interaktive JavaScript-Sitzung wie diese zu starten:

    $node

    Welcome to Node.js v14.15.0.

    Type .help for more information.

    > .help

    .break    Sometimes you get stuck, this gets you out

    .clear    Alias for .break

    .editor  Enter editor mode

    .exit    Exit the repl

    .help    Print this help message

    .load    Load JS from a file into the REPL session

    .save    Save all evaluated commands in this REPL session to a file

    Press ^C to abort current expression, ^D to exit the repl

    > let x = 2, y = 3;

    undefined

    > x + y

    5

    > (x === 2) && (y === 3)

    true

    > (x > 3) || (y < 3)

    false

    1.2Hello World

    Wenn Sie bereit sind, mit längeren Codeblöcken zu experimentieren, eignen sich diese zeilenbasierten interaktiven Umgebungen normalerweise nicht mehr besonders, und Sie werden es wahrscheinlich vorziehen, Ihren Code in einem Texteditor zu schreiben. Von dort aus können Sie den Code in die JavaScript-Konsole oder in eine Node-Sitzung kopieren. Oder Sie speichern Ihren Code in einer Datei (die herkömmliche Dateinamenserweiterung für JavaScript-Code lautet .js) und führen dann diese Datei mit Node aus:

    $ node snippet.js

    Wenn Sie Node in einer solchen nicht interaktiven Weise verwenden, wird der Wert des ausgeführten Codes nicht automatisch ausgegeben, sodass Sie das selbst vornehmen müssen. Verwenden Sie die Funktion console.log(), um Text und andere JavaScript-Werte in Ihrem Terminalfenster oder in der Konsole der Entwicklerwerkzeuge eines Browsers anzuzeigen – zum Beispiel indem Sie eine Datei hello.js erstellen, die folgende Codezeile enthält:

    console.log(Hello World!);

    Wenn Sie diese Datei mit nodehello.js ausführen, wird die Meldung »Hello World!« ausgegeben.

    Möchten Sie die gleiche Nachricht in der JavaScript-Konsole eines Webbrowsers ausgeben, erstellen Sie eine neue Datei mit dem Namen hello.html und fügen diesen Text darin ein:

    Dann laden Sie hello.html in Ihren Webbrowser mit einer file://-URL wie dieser:

    file:///Users/username/javascript/hello.html

    Öffnen Sie nun das Fenster der Entwicklertools, um die Begrüßung in der Konsole zu sehen.

    1.3Ein Rundgang durch JavaScript

    Dieser Abschnitt enthält eine kurze Einführung in die JavaScript-Sprache anhand von Codebeispielen. Nach diesem einführenden Kapitel steigen wir richtig tief in JavaScript ein und beginnen damit ganz weit unten – Kapitel 2 erklärt Dinge wie JavaScript-Kommentare, Semikola und den Unicode-Zeichensatz. In Kapitel 3 wird es schon ein bisschen spannender: Es werden JavaScript-Variablen erklärt sowie die Werte, die man ihnen zuweisen kann.

    Hier ist etwas Beispielcode, der die Höhepunkte dieser beiden Kapitel veranschaulicht:

    // Alles nach einem doppelten Schrägstrich ist ein Kommentar in normaler Sprache.

    // Lesen Sie Kommentare sorgfältig: Sie erläutern den JavaScript-Code.

    // Eine Variable ist ein symbolischer Name für einen Wert.

    // Variablen werden mit dem Schlüsselwort let deklariert:

    let x;                    // Eine Variable namens x deklarieren.

    // Mit dem =-Zeichen können Variablen Werte zugewiesen werden.

    x = 0;                    // Jetzt hat die Variable x den Wert 0.

    x                          // => 0: Eine Variable wird zu ihrem Wert ausgewertet.

    // JavaScript unterstützt eine ganze Reihe von Wertetypen.

    x = 1;                    // Zahlen.

    x = 0.01;                  // Zahlen können ganze oder reelle Zahlen sein.

    x = hello world;        // Textsequenzen in Anführungszeichen.

    x = 'JavaScript';          // Auch einfache Anführungszeichen sind möglich.

    x = true;                  // Ein boolescher Wert.

    x = false;                // Der andere boolesche Wert.

    x = null;                  // null ist ein spezieller Wert, der für kein Wert

    // steht.

    x = undefined;            // undefined ist ein weiterer spezieller Wert wie null.

    Zwei weitere sehr wichtige Datentypen, mit denen man in JavaScript-Programmen arbeiten kann, sind Objekte und Arrays. Diese Typen behandeln wir in den Kapiteln 6 und 7, aber sie sind so wichtig, dass sie Ihnen in diesem Buch bereits viele Male zuvor begegnen werden:

    // Der wichtigste Datentyp in JavaScript ist das Objekt.

    // Ein Objekt ist eine Sammlung von Name/Wert-Paaren

    // (bzw. eine Map, in der Zeichenketten auf Werte abgebildet werden).

    let book = {              // Objekte sind von geschweiften Klammern umschlossen.

    topic: JavaScript,  // Die Eigenschaft topic hat den Wert JavaScript.

    edition: 7            // Die Eigenschaft edition hat den Wert 7.

    };                        // Die geschweifte Klammer markiert das Ende

    // des Objekts.

    // Zugriff auf die Eigenschaften eines Objekts mit . oder []:

    book.topic                // => JavaScript

    book[edition]            // => 7: Eine weitere Möglichkeit, auf

    // Eigenschaftswerte zuzugreifen.

    book.author = Flanagan;  // Neue Eigenschaften durch Zuweisung erstellen.

    book.contents = {};        // {} ist ein leeres Objekt ohne Eigenschaften.

    // Bedingter Zugriff auf Eigenschaften mit ?. (ES2020):

    book.contents?.ch01?.sect1 // => undefined: book.contents hat keine

    // Eigenschaft ch01.

    // JavaScript unterstützt auch Arrays (numerisch indexierte Listen) mit Werten:

    let primes = [2, 3, 5, 7]; // Ein Array mit 4 Werten, begrenzt durch [ und ].

    primes[0]                  // => 2: Das erste Element (Index 0) des Arrays.

    primes.length              // => 4: Anzahl der Elemente im Array.

    primes[primes.length-1]    // => 7: Das letzte Element des Arrays.

    primes[4] = 9;            // Ein neues Element durch Zuweisen hinzufügen.

    primes[4] = 11;            // Oder ein vorhandenes Element durch Zuweisen

    // verändern.

    let empty = [];            // [] ist ein leeres Array ohne Elemente.

    empty.length              // => 0

    // Arrays und Objekte können andere Arrays und Objekte enthalten:

    let points = [            // Ein Array mit 2 Elementen.

    {x: 0, y: 0},          // Jedes Element ist ein Objekt.

    {x: 1, y: 1}

    ];

    let data = {                // Ein Objekt mit 2 Eigenschaften.

    trial1: [[1,2], [3,4]],  // Der Wert jeder Eigenschaft ist ein Array.

    trial2: [[2,3], [4,5]]  // Die Elemente der Arrays sind Arrays.

    };

    Kommentarsyntax in Codebeispielen

    Sie haben vielleicht im vorhergehenden Code bemerkt, dass einige der Kommentare mit einem Pfeil (=>) beginnen. Diese zeigen den Wert, den der Code vor dem Kommentar erzeugt, und sind mein Versuch, eine interaktive JavaScript-Umgebung wie etwa eine Webbrowserkonsole in einem gedruckten Buch nachzubilden.

    Diese // =>-Kommentare dienen ebenfalls als Zusicherungen in Softwaretests (auch als Behauptungen bzw. Assertionen bezeichnet), und ich habe ein Tool geschrieben, um den Code zu testen und dabei zu verifizieren, dass er den im Kommentar angegebenen Wert erzeugt – was, so hoffe ich, dazu beiträgt, die Fehlerzahl in diesem Buch zu verringern.

    Es gibt zwei verwandte Arten von Kommentaren/Zusicherungen. Ein Kommentar der Form // a == 42 bedeutet, dass die Variable a den Wert 42 haben wird, nachdem der Code, der vor dem Kommentar steht, ausgeführt wurde. Ein Kommentar der Form // ! zeigt an, dass der Code in der Zeile vor dem Kommentar eine Ausnahme auslöst (und der Rest des Kommentars nach dem Ausrufezeichen erklärt normalerweise, welche Art von Ausnahme auftritt).

    Solche Kommentare werden Ihnen im gesamten Buch begegnen.

    Die hier dargestellte Syntax zur Auflistung von Array-Elementen innerhalb eckiger Klammern oder zur Abbildung von Bezeichnungen von Objekteigenschaften auf Eigenschaftswerte innerhalb geschweifter Klammern wird als Initialisierungsausdruck bezeichnet – und ist nur eines der Themen von Kapitel 4. Ein Ausdruck ist eine Phrase in JavaScript, die zu einem Wert ausgewertet werden kann. Beispielsweise ist die Verwendung von . und [], um auf den Wert einer Objekteigenschaft oder eines Array-Elements zu verweisen, ein Ausdruck.

    Am häufigsten bildet man Ausdrücke in JavaScript, indem man Operatoren verwendet:

    // Operatoren agieren auf Werten (den Operanden), um einen neuen Wert zu erzeugen.

    // Arithmetische Operatoren gehören zu den einfachsten Operatoren:

    3 + 2                      // => 5: Addition

    3 - 2                      // => 1: Subtraktion

    3 * 2                      // => 6: Multiplikation

    3 / 2                      // => 1.5: Division

    points[1].x - points[0].x  // => 1: Auch komplexere Operanden sind möglich.

    3 + 2                  // => 32: + addiert Zahlen, verkettet Strings.

    // JavaScript bietet einige arithmetische Kurzoperatoren:

    let count = 0;            // Variable definieren.

    count++;                  // Variable inkrementieren.

    count--;                  // Variable dekrementieren.

    count += 2;                // 2 addieren, entspricht count = count + 2;.

    count *= 3;                // Mit 3 multiplizieren, entspricht count = count * 3;.

    count                      // => 6: Variablennamen sind ebenfalls Ausdrücke.

    // Gleichheits- und Relationsoperatoren prüfen, ob zwei Werte gleich, ungleich,

    // kleiner als, größer als usw. sind. Sie werden zu true oder false ausgewertet.

    let x = 2, y = 3;          // Diese =-Zeichen sind Zuweisungen, keine

    // Gleichheitstests.

    x === y                    // => false: Gleichheit.

    x !== y                    // => true: Ungleichheit.

    x < y                      // => true: kleiner als.

    x <= y                    // => true: kleiner als oder gleich.

    x > y                      // => false: größer als.

    x >= y                    // => false: größer als oder gleich.

    two === three          // => false: Die beiden Strings sind verschieden.

    two > three            // => true: tw ist alphabetisch größer als th.

    false === (x > y)          // => true: false ist gleich false.

    // Logische Operatoren kombinieren oder invertieren boolesche Werte:

    (x === 2) && (y === 3)    // => true: Beide Vergleiche sind wahr. && ist AND (UND).

    (x > 3) || (y < 3)        // => false: Keiner der Vergleiche ist wahr.

    // || ist OR (ODER).

    !(x === y)                // => true: ! invertiert einen booleschen Wert.

    Betrachtet man JavaScript-Ausdrücke als Phrasen, wären JavaScript-Anweisungen ganze Sätze. Anweisungen sind das Thema von Kapitel 5. Ein Ausdruck ist, vereinfacht gesagt, etwas, das einen Wert liefert, aber nichts tut. Anweisungen hingegen liefern keinen Wert (zumindest keinen, der uns interessiert), ändern aber den Zustand. Oben haben Sie Variablendeklarationen und Zuweisungsanweisungen gesehen. Die andere große Kategorie von Anweisungen sind Kontrollstrukturen wie z.B. Bedingungen und Schleifen. Beispiele finden Sie weiter unten, nachdem wir die Funktionen behandelt haben.

    Eine Funktion ist ein benannter und parametrisierter Block mit JavaScript-Code, den Sie einmal definieren und dann immer wieder aufrufen können. Funktionen werden formal erst in Kapitel 8 behandelt, aber wie Objekte und Arrays werden sie Ihnen auch vorher schon immer wieder mal begegnen. Hier ein paar einfache Beispiele:

    // Funktionen sind parametrisierte Blöcke mit JavaScript-Code, die wir aufrufen

    // können.

    function plus1(x) {        // Funktion mit dem Namen plus1 und dem

    // Parameter x definieren.

    return x + 1;          // Wert zurückgeben, der um eins größer ist

    // als der übergebene Wert.

    }                          // Funktionen sind in geschweifte Klammern

    // eingeschlossen.

    plus1(y)                  // => 4: y ist (immer noch) 3, also gibt

    // dieser Aufruf 3+1 zurück.

    let square = function(x) { // Funktionen sind Werte und können Variablen

    // zugewiesen werden.

    return x * x;          // Funktionswert berechnen.

    };                        // Semikola kennzeichnen das Ende der Zuweisung.

    square(plus1(y))          // => 16: Zwei Funktionen in einem Ausdruck aufrufen.

    In ES6 und späteren Versionen gibt es eine Kurzschriftsyntax für die Definition von Funktionen. Diese prägnante Syntax verwendet =>, um die Argumentliste vom Funktionskörper zu trennen, daher werden auf diese Weise definierte Funktionen als Pfeilfunktionen bezeichnet. Pfeilfunktionen werden am häufigsten eingesetzt, wenn eine unbenannte Funktion als Argument an eine andere Funktion übergeben werden soll. Verwendet man Pfeilfunktionen, sieht der vorhergehende Code so aus:

    const plus1 = x => x + 1;  // Die Eingabe x wird auf die Ausgabe x + 1 abgebildet.

    const square = x => x * x;  // Die Eingabe x wird auf die Ausgabe x * x abgebildet.

    plus1(y)                    // => 4: Funktionen werden wie sonst auch aufgerufen.

    square(plus1(y))            // => 16

    Wenn wir Funktionen mit Objekten verwenden, erhalten wir Methoden:

    // Werden Funktionen den Eigenschaften eines Objekts zugewiesen, nennen wir sie

    // Methoden. Alle JavaScript-Objekte (einschließlich Arrays) besitzen Methoden:

    let a = [];                // Ein leeres Array anlegen.

    a.push(1,2,3);            // Die Methode push() fügt einem Array Elemente hinzu.

    a.reverse();              // Eine weitere Methode: die Reihenfolge der Elemente

    // umkehren.

    // Wir können auch eigene Methoden definieren. Das Schlüsselwort this bezieht

    // sich auf das Objekt, für das die Methode definiert ist: hier das Array points

    // aus einem vorhergehenden Beispiel.

    points.dist = function() { // Methode zum Berechnen des Abstands zwischen

    // Punkten definieren.

    let p1 = this[0];      // Erstes Element des Arrays, auf dem die Methode

    // aufgerufen wird.

    let p2 = this[1];      // Zweites Element des Arrays this.

    let a = p2.x-p1.x;    // Differenz der x-Koordinaten.

    let b = p2.y-p1.y;    // Differenz der y-Koordinaten.

    return Math.sqrt(a*a + // Der Satz des Pythagoras.

    b*b); // Math.sqrt() zieht die Wurzel.

    };

    points.dist()              // => Math.sqrt(2): Abstand zwischen unseren

    // zwei Punkten.

    Hier erhalten Sie nun wie versprochen einige Funktionen, in denen als Anweisungen häufig genutzte JavaScript-Kontrollstrukturen vorkommen:

    // Zu den JavaScript-Anweisungen gehören auch bedingte Anweisungen und Schleifen,

    // die eine aus C, C++, Java und anderen Sprachen bekannte Syntax nutzen.

    function abs(x) {          // Eine Funktion zur Berechnung des Absolutbetrags.

    if (x >= 0) {          // Die if-Anweisung …

    return x;          // … führt diesen Code aus, wenn der Vergleich

    // wahr ist.

    }                      // Das Ende der if-Anweisung.

    else {                // Die optionale else-Anweisung führt den in ihr

    // enthaltenen Code

    return -x;        // aus, wenn der Vergleich falsch ist.

    }                      // Geschweifte Klammern sind optional, wenn es nur

    // eine Anweisung gibt.

    }                          // Beachten Sie die return-Anweisungen innerhalb

    // von if/else.

    abs(-10) === abs(10)      // => true

    function sum(array) {      // Berechnet die Summe der Elemente eines Arrays.

    let sum = 0;          // Beginnt mit einer Anfangssumme von 0.

    for(let x of array) {  // Schleife über das Array, wobei jedes Element x

    // zugeordnet wird.

    sum += x;          // Aktuellen Elementwert der Summe hinzufügen.

    }                      // Das Ende der for-Schleife.

    return sum;            // Die Summe zurückgeben.

    }

    sum(primes)                // => 28: Summe der ersten 5 Primzahlen 2+3+5+7+11.

    function factorial(n) {    // Eine Funktion zur Berechnung von Fakultäten.

    let product = 1;      // Beginne mit dem Produkt von 1.

    while(n > 1) {        // Wiederhole Anweisungen in {}, solange der Ausdruck

    // in () wahr ist.

    product *= n;      // Kurzform für product = product * n.

    n--;              // Kurzform fürn=n -1.

    }                      // Das Ende der while-Schleife.

    return product;        // Rückgabe des Produkts.

    }

    factorial(4)              // => 24: 1*4*3*2

    function factorial2(n) {  // Eine alternative Version, die eine andere

    // Schleife verwendet.

    let i, product = 1;    // Beginne mit 1.

    for(i=2; i <= n; i++)  // i automatisch von 2 bis n inkrementieren.

    product *= i;      // Wird jedes Mal ausgeführt. {} wird für einzeilige

    // Schleifen nicht benötigt.

    return product;        // Rückgabe der Fakultät.

    }

    factorial2(5)              // => 120: 1*2*3*4*5

    JavaScript unterstützt einen objektorientierten Programmierstil, unterscheidet sich aber deutlich von »klassischen« objektorientierten Programmiersprachen. Kapitel 9 behandelt die objektorientierte Programmierung in JavaScript im Detail anhand vieler Beispiele. Es folgt ein sehr einfaches Beispiel, das zeigt, wie Sie eine JavaScript-Klasse erstellen, die einen zweidimensionalen Punkt repräsentiert. Objekte, die Instanzen dieser Klasse sind, besitzen genau eine Methode namens distance(), die den Abstand des Punkts vom Ursprung berechnet:

    class Point {              // Gemäß Konvention werden Klassennamen großgeschrieben.

    constructor(x, y) {    // Konstruktorfunktion zur Initialisierung neuer

    // Instanzen.

    this.x = x;        // Das Schlüsselwort this bezeichnet das neue Objekt,

    // das initialisiert wird.

    this.y = y;        // Funktionsargumente als Objekteigenschaften speichern.

    }                      // In Konstruktorfunktionen ist keine Rückgabe

    // erforderlich.

    distance() {          // Methode zur Berechnung der Entfernung zwischen

    // Ursprung und Punkt.

    return Math.sqrt(  // Liefert die Quadratwurzel aus x² + y².

    this.x * this.x +  // this bezieht sich auf das Punktobjekt, auf dem

    this.y * this.y    // die Methode distance() aufgerufen wird.

    );

    }

    }

    // Verwenden Sie die Konstruktorfunktion Point() mit new, um Punktobjekte

    // zu erstellen.

    let p = new Point(1, 1);  // Der geometrische Punkt (1,1).

    // Verwenden Sie jetzt eine Methode des Punktobjekts p.

    p.distance()              // => Math.SQRT2

    So weit die Einführung in die grundlegende Syntax und die Fähigkeiten von JavaScript. Es folgen in sich abgeschlossene Kapitel, in denen weitere Sprachmerkmale behandelt werden:

    Kapitel 10, Module

    Zeigt, wie JavaScript-Code in einer Datei oder einem Skript Funktionen und Klassen verwenden kann, die in anderen Dateien oder Skripten definiert sind.

    Kapitel 11, Die JavaScript-Standardbibliothek

    Deckt die eingebauten Funktionen und Klassen ab, die allen JavaScript-Programmen zur Verfügung stehen. Dazu gehören wichtige Datenstrukturen wie Maps und Sets, eine Klasse für reguläre Ausdrücke für die Suche nach Textmustern, Funktionen zur Serialisierung von JavaScript-Datenstrukturen und vieles mehr.

    Kapitel 12, Iteratoren und Generatoren

    Erklärt, wie die for/of-Schleife funktioniert und wie Sie Ihre eigenen Klassen mit for/of iterierbar machen können. Daneben werden Generatorfunktionen und die yield-Anweisung behandelt.

    Kapitel 13, Asynchrones JavaScript

    Untersucht eingehend die asynchrone Programmierung in JavaScript, wobei Callbacks und Events, Promise-basierte APIs und die Schlüsselwörter async und await behandelt werden. Obwohl JavaScript im Kern nicht asynchron ist, sind asynchrone APIs Standard sowohl in Webbrowsern als auch in Node, und in diesem Kapitel werden die Techniken für die Arbeit mit diesen APIs erläutert.

    Kapitel 14, Metaprogrammierung

    Stellt eine Reihe fortgeschrittener Funktionen von JavaScript vor, die für Programmierer interessant sind, die Codebibliotheken schreiben, um diese anderen JavaScript-Programmierern zur Verfügung zu stellen.

    Kapitel 15, JavaScript im Webbrowser

    Stellt die Hostumgebung des Webbrowsers vor, erklärt, wie Webbrowser JavaScript-Code ausführen, und behandelt die wichtigsten der vielen von Webbrowsern definierten APIs. Dies ist bei Weitem das längste Kapitel des Buchs.

    Kapitel 16, Serverseitiges JavaScript mit Node

    Stellt die Hostumgebung von Node vor und behandelt das grundlegende Programmiermodell sowie die für das Verständnis wichtigsten Datenstrukturen und APIs.

    Kapitel 17, JavaScript-Werkzeuge und -Erweiterungen

    Deckt weitverbreitete Werkzeuge und Spracherweiterungen ab, die man kennen sollte und die Sie zu einem produktiveren Programmierer machen können.

    1.4Beispiel: Häufigkeitshistogramme

    Dieses Kapitel schließt mit einem kurzen, aber nicht trivialen JavaScript-Programm. Beispiel 1-1 ist ein Node-Programm, das Text von der Standardeingabe liest, aus diesem Text ein Häufigkeitshistogramm der vorkommenden Zeichen berechnet und dieses Histogramm ausgibt. Sie können das Programm wie folgt aufrufen, um die Zeichenhäufigkeit seines eigenen Quelltexts zu analysieren:

    $ node charfreq.js < charfreq.js

    T: ########### 11.22%

    E: ########## 10.15%

    R: ####### 6.68%

    S: ###### 6.44%

    A: ###### 6.16%

    N: ###### 5.81%

    O: ##### 5.45%

    I: ##### 4.54%

    H: #### 4.07%

    C: ### 3.36%

    L: ### 3.20%

    U: ### 3.08%

    /: ### 2.88%

    Dieses Beispiel verwendet eine Reihe fortgeschrittener JavaScript-Funktionen und soll demonstrieren, wie JavaScript-Programme in der realen Welt aussehen können. Falls Sie den Code noch nicht vollständig verstehen, macht das nichts – ich verspreche Ihnen, dass in den folgenden Kapiteln alles erklärt wird.

    Beispiel 1-1: Berechnung von Häufigkeitshistogrammen mit JavaScript

    /**

    * Dieses Node-Programm liest Text aus der Standardeingabe, berechnet für

    * jedes Zeichen in diesem Text die Häufigkeit seines Vorkommens und zeigt

    * ein Histogramm der am häufigsten verwendeten Zeichen. Zur Ausführung ist

    * Node 12 oder höher erforderlich.

    *

    * In einer Unix-artigen Umgebung können Sie das Programm wie folgt aufrufen:

    *    node charfreq.js < corpus.txt

    */

    // Diese Klasse erweitert Map so, dass die get()-Methode statt null den angegebenen

    // Wert zurückgibt, falls der Schlüssel key nicht in der Map vorkommt.

    class DefaultMap extends Map {

    constructor(defaultValue) {

    super();                          // Ruft den Konstruktor der Superklasse auf.

    this.defaultValue = defaultValue; // Standardwert merken.

    }

    get(key) {

    if (this.has(key)) {              // Wenn der Schlüssel bereits in der Map

    // vorkommt,

    return super.get(key);        // wird dessen Wert aus der Superklasse

    // zurückgegeben.

    }

    else {

    return this.defaultValue;    // Gibt ansonsten den Standardwert zurück.

    }

    }

    }

    // Diese Klasse berechnet und zeigt Buchstabenhäufigkeitshistogramme.

    class Histogram {

    constructor() {

    this.letterCounts = new DefaultMap(0);  // Zuordnung von Buchstaben

    // zu Zählwerten.

    this.totalLetters = 0;                  // Wie viele Buchstaben insgesamt?

    }

    // Diese Funktion aktualisiert das Histogramm mit den Zeichen des Texts.

    add(text) {

    // Entfernt Leerzeichen aus dem Text und konvertiert in Großbuchstaben.

    text = text.replace(/\s/g, ).toUpperCase();

    // Schleife über die Zeichen des Texts.

    for(let character of text) {

    let count = this.letterCounts.get(character); // Alten Zählwert auslesen.

    this.letterCounts.set(character, count+1);    // Inkrementieren.

    this.totalLetters++;

    }

    }

    // Konvertiert das Histogramm in eine Zeichenfolge, die eine ASCII-Grafik anzeigt.

    toString() {

    // Konvertiert die Map in ein Array von Schlüssel/Wert-Arrays.

    let entries = […this.letterCounts];

    // Sortiert das Array zuerst nach Anzahl und dann alphabetisch.

    entries.sort((a,b) => {              // Eine Funktion zur Festlegung der

    // Sortierreihenfolge.

    if (a[1] === b[1]) {            // Wenn die Zählwerte identisch ist.

    return a[0] < b[0] ? -1 : 1; // Alphabetisch sortieren.

    } else {                        // Wenn die Zählwerte abweichen.

    return b[1] - a[1];          // Sortierung nach der höchsten Anzahl.

    }

    });

    // Rechnet die Ergebnisse in Prozentzahlen um.

    for(let entry of entries) {

    entry[1] = entry[1] / this.totalLetters*100;

    }

    // Alle Einträge unter 1 % fallen lassen.

    entries = entries.filter(entry => entry[1] >= 1);

    // Konvertiert jeden Eintrag in eine Textzeile.

    let lines = entries.map(

    ([l,n]) => `${l}: ${#.repeat(Math.round(n))} ${n.toFixed(2)}%`

    );

    // Und gibt die verketteten Zeilen, getrennt durch Zeilenumbruchzeichen,

    // zurück.

    return lines.join(\n);

    }

    }

    // Diese asynchrone (ein Promise zurückgebende) Funktion erzeugt ein Histogrammobjekt,

    // liest Textblöcke asynchron aus der Standardeingabe und fügt diese Blöcke dem

    // Histogramm hinzu. Wenn das Ende des Streams erreicht wird, gibt es das Histogramm

    // zurück.

    async function histogramFromStdin() {

    process.stdin.setEncoding(utf-8); // Unicode-Strings lesen, nicht Bytes.

    let histogram = new Histogram();

    for await (let chunk of process.stdin) {

    histogram.add(chunk);

    }

    return histogram;

    }

    // Die folgende letzte Codezeile ist der Hauptteil des Programms.

    // Darin wird aus der Standardeingabe ein Histogrammobjekt erstellt und ausgegeben.

    histogramFromStdin().then(histogram => { console.log(histogram.toString()); });

    1.5Zusammenfassung

    In diesem Buch wird JavaScript von Grund auf erklärt. Deshalb beginnen wir auch mit grundlegenden Dingen wie Kommentaren, Identifiern, Variablen und Datentypen, um dann zu Ausdrücken, Anweisungen, Objekten und Funktionen überzugehen und schließlich hochsprachliche Abstraktionen wie Klassen und Module zu behandeln. Ich nehme das Wort Handbuch im Titel dieses Buchs ernst: In den kommenden Kapiteln wird die Sprache in einer Detailgenauigkeit erklärt, die auf den ersten Blick abschreckend wirken mag. Um JavaScript wahrhaft zu beherrschen, muss man jedoch die Details verstehen, und ich hoffe, dass Sie sich die Zeit nehmen, dieses Buch von vorne bis hinten durchzulesen. Aber das muss natürlich nicht in einem Rutsch geschehen. Wenn Sie das Gefühl haben, sich in einem Abschnitt festgefahren zu haben, springen Sie einfach zum nächsten. Sie können später zu dem entsprechenden Abschnitt zurückkehren und sich den Details widmen, sobald Sie eine grundlegende Kenntnis der Sprache als Ganzes gewonnen haben.

    KAPITEL 2

    Die lexikalische Struktur

    Die lexikalische Struktur einer Programmiersprache ist der Satz elementarer Regeln, der festlegt, wie Programme in dieser Sprache geschrieben werden müssen. Es ist die Syntax der untersten Ebene einer Sprache: Sie legt beispielsweise fest, wie Variablennamen gebildet werden, welche Zeichen Kommentare einleiten oder begrenzen und wie eine Programmanweisung von der nächsten unterschieden bzw. getrennt wird. Dieses kurze Kapitel dokumentiert die lexikalische Struktur von JavaScript. Es behandelt:

    Groß-/Kleinschreibung, Leerzeichen und Zeilenumbrüche

    Kommentare

    Literale

    Identifier und reservierte Wörter

    Unicode

    Optionale Semikola

    2.1Der Text eines JavaScript-Programms

    JavaScript ist eine Sprache, in der zwischen Groß- und Kleinschreibung unterschieden wird. Das bedeutet, dass Schlüsselwörter der Sprache, Variablen, Funktionsnamen und andere Identifier immer mit einer konsistenten Groß-/Kleinschreibung der enthaltenen Buchstaben eingegeben werden müssen. Das Schlüsselwort while muss zum Beispiel mit kleinem »w«, also »while«, eingegeben werden, nicht »While« oder »WHILE«. Dementsprechend wären online, Online, OnLine und ONLINE vier verschiedene Variablennamen.

    Innerhalb von Programmen ignoriert JavaScript Leerzeichen, die zwischen Tokens (den lexikalischen Grundeinheiten) stehen. In den meisten Fällen ignoriert JavaScript auch Zeilenumbrüche (eine Ausnahme wird in 2.6 beschrieben). Da Sie also Leerzeichen und Zeilenumbrüche frei verwenden können, lassen sich Programme sauber und konsistent formatieren und einrücken, sodass der Code leicht lesbar und gut verständlich ist.

    Zusätzlich zum regulären Leerzeichen (\u0020) erkennt JavaScript auch Tabulatoren, verschiedene ASCII-Steuerzeichen sowie unterschiedliche Unicode-Leerzeichen als Whitespace-Zeichen¹. Als Zeilenabschlüsse versteht JavaScript Zeilenumbrüche (LF, Line Feed), Wagenrückläufe (CR, Carriage Return) und eine Wagenrücklauf-/Zeilenvorschubsequenz (CRLF: Carriage Return/Line Feed).

    2.2Kommentare

    JavaScript unterstützt zwei Arten von Kommentaren: Als Kommentar betrachtet und von JavaScript ignoriert wird Text, der zwischen der Zeichenfolge // und dem Ende einer Zeile steht, sowie Text, der zwischen den Zeichenfolgen /* und */ steht. Diese zweite Kommentarvariante darf mehrere Zeilen lang sein, aber nicht verschachtelt werden. Alle folgenden Codezeilen sind korrekte JavaScript-Kommentare:

    // Dies ist ein einzeiliger Kommentar.

    /* Das hier ist ebenfalls ein Kommentar. */ // Und hier ein weiterer.

    /*

    * Das ist ein mehrzeiliger Kommentar. Die zusätzlichen *-Zeichen am Anfang jeder

    * Zeile sind nicht zwingend vorgeschrieben, aber sie sehen einfach cool aus –

    * und verbessern die Lesbarkeit.

    */

    2.3Literale

    Ein Literal ist ein Datenwert, der direkt in einem Programm erscheint. Die folgenden Elemente sind jeweils Literale:

    12              // Die Zahl zwölf.

    1.2              // Die Zahl eins Komma zwei.

    hello world    // Eine Zeichenfolge.

    'Hi'            // Eine weitere Zeichenfolge.

    true            // Ein boolescher Wert.

    false            // Ein weiterer boolescher Wert.

    null            // Abwesenheit eines Objekts.

    Vollständige Informationen zu numerischen Literalen (auch Zahlliterale genannt) und String-Literalen finden Sie in Kapitel 3.

    2.4Identifier und reservierte Wörter

    Ein Identifier – der englische Originalbegriff Identifier wird im Deutschen ebenfalls häufig benutzt – ist schlicht ein Name. In JavaScript werden Identifier verwendet, um Konstanten, Variablen, Eigenschaften, Funktionen und Klassen zu benennen und um Labels für bestimmte Schleifen im JavaScript-Code bereitzustellen. Ein JavaScript-Identifier muss mit einem Buchstaben, einem Unterstrich (_) oder einem Dollarzeichen ($) beginnen. Danach folgende Zeichen können Buchstaben, Ziffern, Unterstriche oder Dollarzeichen sein. (Ziffern sind als erstes Zeichen nicht erlaubt, damit JavaScript auf einfache Weise Identifier und Zahlen unterscheiden kann.)

    i

    my_variable_name

    v13

    _dummy

    $str

    Wie auch in jeder anderen Programmiersprache reserviert JavaScript bestimmte Identifier für den Einsatz durch die Sprache selbst. Diese »reservierten Wörter« dürfen nicht als gewöhnliche Identifier verwendet werden. Sie sind im nächsten Abschnitt aufgeführt.

    2.4.1Reservierte Wörter

    Die folgenden Wörter sind Teil der Sprache JavaScript. Viele davon (wie if, while und for) sind reservierte Schlüsselwörter, die nicht als Namen von Konstanten, Variablen, Funktionen oder Klassen genutzt werden dürfen (obwohl sie alle als Namen von Eigenschaften innerhalb eines Objekts verwendet werden können). Andere (wie from, of, get und set) werden in bestimmten Kontexten eingesetzt, die syntaktisch eindeutig sind, und sind als Identifier erlaubt. Wieder andere Schlüsselwörter (wie z.B. let) können nicht vollständig reserviert werden, um die Rückwärtskompatibilität mit älteren Programmen zu erhalten. Aus diesem Grund bestimmen komplexe Regeln, wann sie als Identifier verwendet werden können. (let kann z.B. zusammen mit var außerhalb einer Klasse als Variablenname deklariert werden, nicht aber innerhalb mit const.) Am einfachsten ist es, alle diese Wörter als Identifier zu vermeiden – mit Ausnahme von from, set und target, die man problemlos und sicher einsetzen kann und deren Verwendung durchaus üblich ist.

    as      const      export    get          null    target  void

    async  continue  extends    if          of      this    while

    await  debugger  false      import      return  throw    with

    break  default    finally    in          set      true    yield

    case    delete    for        instanceof  static  try

    catch  do        from      let          super    typeof

    class  else      function  new          switch  var

    JavaScript reserviert außerdem einige Wörter, die im Moment noch nicht offiziell Teil der Sprache sind, bei Bedarf aber in künftigen Versionen genutzt werden könnten.

    enum  implements  interface  package  private  protected  public

    Aus historischen Gründen sind arguments und eval unter bestimmten Umständen nicht als Identifier erlaubt – sie sollten am besten ganz vermieden werden.

    2.5Unicode

    JavaScript-Programme werden im Unicode-Zeichensatz geschrieben, und Sie können beliebige Unicode-Zeichen in Zeichenfolgen und Kommentaren verwenden. Aus Gründen der Portabilität und der einfachen Bearbeitung ist es üblich, in Identifiern lediglich ASCII-Buchstaben und -Ziffern zu verwenden. Das ist aber nur eine Programmierkonvention. Die Sprache erlaubt Unicode-Buchstaben, -Ziffern und -Ideogramme (aber keine Emojis) in Identifiern. Das bedeutet, dass man mathematische Symbole und Wörter aus nicht englischen Sprachen als Konstanten und Variablen verwenden kann:

    const π = 3.14;

    const sí = true;

    2.5.1Unicode-Escape-Sequenzen

    Es gibt Hard- und Software, die nicht in der Lage sind, alle Unicode-Zeichen anzuzeigen, als Eingabe entgegenzunehmen oder korrekt zu verarbeiten. Um Programmierer und Systeme zu unterstützen, die ältere Technologien verwenden, definiert JavaScript Escape-Sequenzen. Mit ihnen können Unicode-Zeichen mithilfe von ASCII-Zeichen geschrieben werden. Diese Unicode-Escape-Sequenzen beginnen mit den beiden Zeichen \u, gefolgt von entweder genau vier Hexadezimalziffern (unter Verwendung der Groß- oder Kleinbuchstaben A bis F) oder einer bis sechs Hexadezimalziffern in geschweiften Klammern. Unicode-Escape-Sequenzen dürfen in JavaScript-String-Literalen, Literalen für reguläre Ausdrücke und Identifiern (aber nicht in spracheigenen Schlüsselwörtern) vorkommen. Die Unicode-Escape-Sequenz für das Zeichen »é« ist beispielsweise \u00E9. Hier sind drei verschiedene Möglichkeiten, einen Variablennamen zu schreiben, der dieses Zeichen enthält:

    let café = 1; // Definieren Sie eine Variable mit einem Unicode-Zeichen.

    caf\u00e9    // => 1; Zugriff auf die Variable mit einer Escape-Sequenz.

    caf\u{E9}    // => 1; Eine andere Form der gleichen Escape-Sequenz.

    Frühe Versionen von JavaScript unterstützten nur vierstellige Escape-Sequenzen. Die Version mit geschweiften Klammern wurde in ES6 eingeführt, um Unicode-Codepoints wie z.B. Emojis, die mehr als 16 Bit benötigen, besser zu unterstützen:

    console.log(\u{1F600});  // Gibt ein Smiley-Emoji aus.

    Unicode-Escape-Sequenzen können auch in Kommentaren vorkommen. Dort werden sie aber einfach als ASCII-Zeichen behandelt (und nicht als Unicode), da Kommentare beim Ausführen des Codes ignoriert werden.

    2.5.2Unicode-Normalisierung

    Wenn Sie in Ihren JavaScript-Programmen Zeichen verwenden, die nicht zum ASCII-Standard gehören, müssen Sie sich bewusst sein, dass Unicode mehr als eine Art der Codierung desselben Zeichens erlaubt. Der aus einem Zeichen bestehende String »é« kann z.B. als einzelnes Unicode-Zeichen \u00E9 oder als reguläres ASCII-»e«, gefolgt von dem Zeichen \u0301, um den Accent aigu hinzuzufügen, dargestellt werden. In einem Texteditor werden beide Codierungen gleich aussehen. Dennoch verwenden sie unterschiedliche Binärcodierungen, und JavaScript erkennt diesen Unterschied, was zu sehr verwirrenden Problemen führen kann:

    const café = 1;  // Diese Konstante wird caf\u{e9} genannt.

    const café = 2;  // Diese Konstante heißt anders: cafe\u{301}.

    café  // => 1: Diese Konstante hat einen bestimmten Wert.

    café  // => 2: Aber diese nicht unterscheidbare Konstante hat einen anderen Wert.

    Der Unicode-Standard definiert die bevorzugte Codierung für alle Zeichen und legt ein Normalisierungsverfahren fest, um Text in eine kanonische Form umzuwandeln, die für Vergleiche geeignet ist. JavaScript geht davon aus, dass der Quellcode, den es interpretiert, bereits normalisiert wurde, und führt von sich aus keine Normalisierung durch. Wenn Sie planen, Unicode-Zeichen in Ihren JavaScript-Programmen zu verwenden, sollten Sie sicherstellen, dass Ihr Editor oder ein anderes Tool eine Unicode-Normalisierung Ihres Quellcodes durchführt. So können Sie verhindern, dass Sie am Ende unterschiedliche, aber visuell nicht unterscheidbare Identifier erhalten.

    2.6Optionale Semikola

    Wie viele andere Programmiersprachen verwendet auch JavaScript das Semikolon (;) zur Trennung von Anweisungen (siehe Kapitel 5). Das ist wichtig, um die Bedeutung Ihres Codes klarzustellen: Ohne Trennzeichen könnte das Ende einer Anweisung als Anfang der nächsten interpretiert werden oder umgekehrt. Normalerweise können Sie in JavaScript das Semikolon zwischen zwei Anweisungen weglassen, wenn diese Anweisungen in getrennten Zeilen stehen. (Am Ende eines Programms ist ebenfalls kein Semikolon vorgeschrieben. Das Gleiche gilt, wenn das folgende Token in einem Programm eine schließende geschweifte Klammer (}) ist.) Viele JavaScript-Programmierer (und ich im Code dieses Buchs) verwenden Semikola, um explizit das Ende von Anweisungen zu markieren, auch wenn es an diesen Stellen eigentlich nicht nötig ist. Bei einer anderen stilistischen Variante werden Semikola nach Möglichkeit weggelassen und nur in den wenigen Situationen verwendet, in denen sie tatsächlich vorgeschrieben sind. Für welche dieser Varianten Sie sich auch entscheiden – es gibt einige Auswirkungen optionaler Semikola, die Sie kennen sollten.

    Betrachten Sie den folgenden Code. Da die beiden Anweisungen in zwei separaten Zeilen stehen, könnten Sie das erste Semikolon weglassen:

    a = 3;

    b = 4;

    Schreibt man die Anweisungen jedoch folgendermaßen, ist das erste Semikolon unbedingt erforderlich:

    a = 3; b = 4;

    Beachten Sie bitte, dass JavaScript nicht jeden Zeilenumbruch als Semikolon behandelt: Das passiert normalerweise nur, wenn es den Code nicht parsen kann, ohne ein implizites Semikolon hinzuzufügen. Formeller ausgedrückt (und mit drei Ausnahmen, die etwas später beschrieben werden): JavaScript behandelt einen Zeilenumbruch als Semikolon, wenn das nächste Nicht-Leerzeichen nicht als Fortsetzung der aktuellen Anweisung interpretiert werden kann. Betrachten Sie diesen Code:

    let a

    a

    =

    3

    console.log(a)

    JavaScript interpretiert ihn folgendermaßen:

    let a; a = 3; console.log(a);

    JavaScript behandelt den ersten Zeilenumbruch als Semikolon, weil es den Code let a a ohne Semikolon nicht parsen kann. Das zweite a könnte allerdings auch als eigenständige Anweisung a; interpretiert werden. JavaScript behandelt den zweiten Zeilenumbruch jedoch nicht als Semikolon, weil es die längere Anweisung a = 3; weiter parsen kann.

    Diese Regeln, anhand deren das Ende von Anweisungen erkannt wird, können zu einigen überraschenden Situationen führen. Folgender Code scheint aus zwei eigenständigen Anweisungen zu bestehen, die durch einen Zeilenumbruch getrennt werden:

    let y = x + f

    (a+b).toString()

    Die Klammern zu Beginn der zweiten Zeile können aber auch als ein Funktionsaufruf auf dem f-Element der ersten Zeile interpretiert werden, sodass JavaScript den Code folgendermaßen lesen würde:

    let y = x + f(a+b).toString();

    Es ist ziemlich unwahrscheinlich, dass eine solche Interpretation beabsichtigt ist. Hier ist also explizit ein Semikolon erforderlich, damit die Anweisungen tatsächlich separat behandelt werden.

    Allgemein kann man sagen: Wenn eine Anweisung mit (, [, /, + oder - beginnt, besteht die Möglichkeit, dass sie als Fortsetzung der vorherigen Anweisung interpretiert wird. Anweisungen, die mit /, + oder - beginnen, sind in der Praxis recht selten, aber Anweisungen, die mit ( und [ beginnen, sind – zumindest in einigen JavaScript-Programmierstilen – keineswegs ungewöhnlich. Manche Programmierer stellen derartigen Anweisungen zur Sicherheit ein Semikolon voran, damit der Code auch dann noch korrekt funktioniert, wenn die vorhergehende Anweisung abgeändert und ein eventuell zuvor vorhandenes abschließendes Semikolon entfernt wird:

    let x = 0                        // Semikolon hier weggelassen.

    ;[x,x+1,x+2].forEach(console.log) // Ein defensives Semikolon sorgt für

    // die sichere Trennung der Anweisungen.

    Es gibt drei Ausnahmen von der allgemeinen Regel, dass JavaScript Zeilenumbrüche als Semikolon interpretiert, wenn es die zweite Zeile nicht als Fortsetzung der Anweisung der ersten Zeile parsen kann. Die erste Ausnahme betrifft die Anweisungen return, throw, yield, break und continue (siehe Kapitel 5). Diese Anweisungen stehen häufig allein, manchmal aber folgt auf sie ein Identifier oder Ausdruck. Folgt nach einem dieser Wörter (vor irgendwelchen weiteren Tokens) ein Zeilenumbruch, interpretiert JavaScript diesen Zeilenumbruch immer als Semikolon. Schreiben Sie beispielsweise

    return

    true;

    geht JavaScript davon aus, dass Sie Folgendes meinen:

    return; true;

    Wahrscheinlich haben Sie aber eher dies im Sinn gehabt:

    return true;

    Das bedeutet, dass Sie keinen Zeilenumbruch zwischen return, break oder continue und dem Ausdruck einfügen dürfen, der dem Schlüsselwort folgt. Machen Sie es trotzdem, wird die Ausführung Ihres Codes vermutlich fehlschlagen – und zwar auf eine Weise, die nur schwer zu durchschauen oder zu debuggen ist.

    Die zweite Ausnahme betrifft die Operatoren ++ und -- (siehe 4.8). Diese Operatoren können als Präfixoperatoren vor oder als Postfixoperatoren nach einem Ausdruck eingesetzt werden. Möchten Sie einen dieser Operatoren als Postfixoperator benutzen, muss er in der gleichen Zeile stehen wie der Ausdruck, auf den er angewandt werden soll. Die dritte Ausnahme betrifft Funktionen, die mit der kompakten Pfeilnotation definiert sind: Der =>-Pfeil selbst muss in derselben Zeile wie die Parameterliste stehen.

    2.7Zusammenfassung

    In diesem Kapitel haben wir uns damit beschäftigt, wie die Syntax von JavaScript-Programmen auf der untersten lexikalischen Ebene aussieht. Das nächste Kapitel führt uns einen Schritt weiter und stellt die primitiven Datentypen und Werte (Zahlen, Zeichenketten usw.) vor, die als grundlegende Recheneinheiten für JavaScript-Programme dienen.

    KAPITEL 3

    Typen, Werte und Variablen

    Computerprogramme arbeiten, indem sie Werte wie etwa die Zahl 3,14 oder den Text »Hallo Welt.« manipulieren. Die unterschiedlichen Arten von Werten, die in einer Programmiersprache repräsentiert und manipuliert werden können, bezeichnet man als Datentypen (oder kurz Typen), und der Satz unterstützter Datentypen ist eines der grundlegendsten Kennzeichen einer Programmiersprache. Wenn ein Programm einen Wert zur späteren Verwendung aufbewahren muss, weist es den Wert einer Variablen zu (oder »speichert« ihn in einer solchen). Variablen haben Namen, die wir in unseren Programmen verwenden, um auf Werte zu verweisen. Ein weiteres grundlegendes Kennzeichen einer Programmiersprache ist die Art und Weise, in der Variablen funktionieren. Dieses Kapitel erklärt Typen, Werte und Variablen in JavaScript. Es beginnt mit einem Überblick und einigen Definitionen.

    3.1Übersicht und Definitionen

    JavaScript-Datentypen lassen sich in zwei Kategorien unterteilen: primitive Typen und Objekttypen. Zu den primitiven Datentypen von JavaScript zählen Zahlen, Strings (im Deutschen auch oft Zeichenfolgen oder Zeichenketten genannt) und boolesche Wahrheitswerte. Ein wesentlicher Teil dieses Kapitels ist einer detaillierten Erklärung der numerischen (siehe 3.2) und String-Typen (siehe 3.3) in JavaScript gewidmet. Booleans werden in 3.4 behandelt.

    Die speziellen JavaScript-Werte null und undefined sind primitive Werte, aber weder Zahlen noch Strings noch boolesche Werte. Beide werden in der Regel als einzige Mitglieder ihres jeweils eigenen speziellen Typs betrachtet. In 3.5 erfahren Sie mehr über null und undefined. In ES6 ist ein neuer spezieller Typ – das Symbol – hinzugekommen, mit dessen Hilfe Spracherweiterungen definiert werden können, ohne die Rückwärtskompatibilität zu beeinträchtigen. Symbole werden kurz in 3.6 behandelt.

    Jeder JavaScript-Wert, der keine Zahl, kein String, kein boolescher Wert, kein Symbol, nicht null und nicht undefined ist, ist ein Objekt. Ein Objekt (das heißt ein Exemplar des Typs Object) ist eine Sammlung von Eigenschaften, die jeweils einen Namen und einen Wert haben (entweder einen primitiven Wert oder ein anderes Objekt). Ein ganz besonderes Objekt, das globale Objekt, wird in 3.7 behandelt. Eine übergreifendere und ausführlichere Behandlung von Objekten im Allgemeinen finden Sie in Kapitel 6.

    Ein normales JavaScript-Objekt ist nichts anderes als eine ungeordnete Sammlung benannter Werte. In JavaScript gibt es außerdem eine spezielle Art von Objekt, das als Array bezeichnet wird. Ein Array ist eine geordnete Sammlung nummerierter Werte. Für die Arbeit mit Arrays – die einige spezielle Verhaltensweisen besitzen, die sie von gewöhnlichen Objekten unterscheiden – bietet JavaScript eine besondere Syntax. Arrays werden detailliert in Kapitel 7 behandelt.

    Neben grundlegenden Objekten und Arrays definiert JavaScript eine Reihe weiterer nützlicher Objekttypen. Ein Set-Objekt stellt einen Satz von Werten dar, ein Map-Objekt dagegen stellt eine Zuordnung von Schlüsseln zu Werten dar. Verschiedene typisierte Arrays erleichtern Operationen auf Arrays von Bytes und anderen binären Daten. Der RegExp-Datentyp repräsentiert Textmuster und ermöglicht ausgeklügelte Vergleichs-, Such- und Ersetzungsoperationen auf Zeichenketten. Der Date-Datentyp stellt Datum und Uhrzeit dar und unterstützt rudimentäre Rechenoperationen mit Datumswerten. Der Fehlertyp Error und dessen Untertypen stellen Fehler dar, die beim Ausführen von JavaScript-Code auftreten können. Alle diese Typen werden in Kapitel 11 behandelt.

    JavaScript unterscheidet sich von statischeren Sprachen dadurch, dass Funktionen und Klassen nicht nur Teil der Sprachsyntax, sondern selbst Werte sind, die von JavaScript-Programmen manipuliert werden können. Wie alle nicht primitiven JavaScript-Werte sind Funktionen und Klassen eine spezialisierte Art von Objekt. Sie werden ausführlich in den Kapiteln 8 und 9 behandelt.

    Der JavaScript-Interpreter führt im Rahmen der Speicherverwaltung eine automatische Speicherbereinigung (Garbage Collection) durch. Als JavaScript-Programmierer muss man sich in der Regel also nicht um das Löschen oder die Deallokation von Objekten oder anderen Werten kümmern. Kann auf einen Wert nicht mehr zugegriffen werden – wenn ein Programm keine Möglichkeit mehr hat, darauf zu verweisen –, weiß der Interpreter, dass der Wert nicht mehr verwendet werden kann, und gibt automatisch den durch den Wert belegten Speicher frei. (Als JavaScript-Programmierer muss man darauf achten, dass Werte nicht versehentlich länger als nötig für das Programm »erreichbar« bleiben und der belegte Speicher deshalb nicht freigegeben werden kann.)

    JavaScript unterstützt einen objektorientierten Programmierstil. Lax formuliert, bedeutet dies, dass man keine global definierten Funktionen nutzt, die auf Werten unterschiedlicher Typen operieren, sondern dass die Datentypen selbst Methoden für die Arbeit mit Werten definieren. Wollen wir beispielsweise die Elemente in einem Array a sortieren, übergeben wir a nicht an irgendeine sort()-Funktion. Stattdessen rufen wir die sort()-Methode von a auf:

    a.sort();    // Die objektorientierte Version von sort(a).

    Die Definition von Methoden wird in Kapitel 9 behandelt. Technisch gesehen, besitzen nur JavaScript-Objekte Methoden. Zahlen, Zeichenfolgen, boolesche Werte und Symbolwerte verhalten sich jedoch ebenfalls so, als besäßen sie Methoden. In JavaScript sind null und undefined die einzigen Werte, auf denen keine Methoden aufgerufen werden können.

    Die Objekttypen von JavaScript sind veränderbar, die primitiven Typen sind unveränderbar. Der Wert eines veränderbaren Typs ist mutabel: Ein JavaScript-Programm kann die Werte von Objekteigenschaften und Array-Elementen ändern. Zahlen, boolesche Werte, Symbole, null und undefined sind unveränderbar – es ergäbe nicht einmal Sinn, von der Änderung des Werts einer Zahl zu sprechen. Man könnte Strings als Arrays von Zeichen betrachten und deshalb vielleicht erwarten, dass sie veränderbar seien. Strings sind in JavaScript aber unveränderbar: Sie können auf die Zeichen an einer beliebigen Position einer Zeichenfolge zugreifen, sie aber nicht verändern. Die Unterschiede zwischen veränderbaren und unveränderbaren Werten werden genauer untersucht in 3.8.

    JavaScript wandelt Werte großzügig von einem Typ in einen anderen Typ um. Übergeben Sie zum Beispiel einem Programm, das einen String erwartet, eine Zahl, wandelt es diese Zahl automatisch für Sie in einen String um. Und geben Sie einen nicht booleschen Wert an einer Stelle an, an der ein boolescher Wert erwartet wird, führt JavaScript die erforderliche Typumwandlung durch. Die Regeln für die Wertumwandlung werden in 3.9 erläutert. Die toleranten Konvertierungsregeln für Werte wirken sich in JavaScript auf die Definition der Gleichheit aus – in 3.9.1 wird beschrieben, welche Typumwandlungen der Gleichheitsoperator == durchführt. (In der Praxis wird auf die Verwendung des als veraltet betrachteten nichtstrikten Gleichheitsoperators == jedoch zugunsten des strikten Gleichheitsoperators === verzichtet, der keine Typumwandlungen vornimmt. Weitere Informationen zu beiden Operatoren finden Sie unter 4.9.1.)

    Konstanten und Variablen ermöglichen Ihnen, Namen zu verwenden, um in Ihren Programmen auf Werte zu verweisen. Konstanten werden mit const deklariert und Variablen mit let (oder in älterem JavaScript-Code mit var). JavaScript-Konstanten und -Variablen sind untypisiert: In den Deklarationen wird nicht angegeben, welche Art von Werten zugewiesen werden sollen. Die Variablendeklaration und -zuweisung wird in 3.10 behandelt.

    Wie Sie bereits an dieser langen Einführung sehen können, ist dies ein umfassendes Kapitel, in dem viele grundlegende Details zur Darstellung und Manipulation von Daten in JavaScript erklärt werden. Legen wir direkt los mit den Einzelheiten zu Zahlen und Text.

    3.2Zahlen

    Der grundlegende numerische Typ in JavaScript, Number, wird verwendet, um Ganzzahlen und (näherungsweise) reelle Zahlen darzustellen. JavaScript stellt Zahlen im 64-Bit-Gleitkommaformat dar, das durch den IEEE-754-Standard¹ definiert ist, und kann damit Zahlenwerte bis hinauf zu ±1.7976931348623157 × 10³⁰⁸ und bis hinab zu ±5 × 10–324 darstellen.

    Das JavaScript-Zahlenformat ermöglicht Ihnen, alle ganzen Zahlen zwischen –9.007.199.254.740.992 (–2⁵³) und 9.007.199.254.740.992 (2⁵³) exakt festzuhalten, jeweils inklusive der Grenzen. Falls Sie größere ganzzahlige Werte als diese verwenden, können Sie in den letzten Ziffern an Genauigkeit verlieren. Beachten Sie jedoch, dass in JavaScript bestimmte Operationen (wie die Indizierung von Arrays und die in Kapitel 4 beschriebenen Bit-Operationen) mit 32-Bit-Ganzzahlen durchgeführt werden. Falls Sie größere Integer-Werte exakt darstellen müssen, schauen Sie sich bitte 3.2.5 an.

    Erscheint eine Zahl unmittelbar in einem JavaScript-Programm, bezeichnet man sie als Zahlliteral. JavaScript unterstützt Zahlliterale in verschiedenen Formaten, die in den folgenden Abschnitten beschrieben werden. Man kann übrigens jedem Zahlliteral ein Minuszeichen (–) voranstellen, um die Zahl als negativ zu kennzeichnen.

    3.2.1Ganzzahlliterale

    In einem JavaScript-Programm wird eine Ganzzahl zur Basis 10 als eine Folge von Ziffern geschrieben, zum Beispiel:

    0

    3

    10000000

    Neben Ganzzahlliteralen zur Basis 10 kennt JavaScript Hexadezimalliterale (zur Basis 16). Ein Hexadezimalliteral beginnt mit den Zeichen 0x oder 0X, auf die eine Reihe hexadezimaler Ziffern folgt. Hexadezimale Ziffern sind die arabischen Ziffern 0 bis 9 und die Buchstaben a (oder A) bis f (oder F), wobei Letztere die Werte von 10 bis 15 repräsentieren. Hier sind einige Beispiele für hexadezimale Ganzzahlliterale:

    0xff      // => 255: (15*16 + 15)

    0xBADCAFE  // => 195939070

    In ES6 und höher können Sie Ganzzahlen auch binär (zur Basis 2) oder oktal (zur Basis 8) mit den Präfixen 0b und 0o (oder 0B und 0O) anstelle von 0x ausdrücken:

    0b10101  // => 21:  (1*16 + 0*8 + 1*4 + 0*2 + 1*1)

    0o377    // => 255: (3*64 + 7*8 + 7*1)

    3.2.2Gleitkommaliterale

    Gleitkommaliterale können einen Dezimalpunkt aufweisen; sie verwenden die traditionelle Syntax für reelle Zahlen. Eine reelle Zahl wird in JavaScript durch einen ganzzahligen Teil, einen Punkt als Dezimaltrenner und einen Nachkommateil der Zahl dargestellt.

    Außerdem können Gleitkommaliterale in sogenannter wissenschaftlicher Notation dargestellt werden. Bei dieser Exponentialdarstellung folgen auf eine reelle Zahl der Buchstabe e (oder E), ein optionales Plus- oder Minuszeichen und ein ganzzahliger Exponent. Eine in dieser Schreibweise dargestellte Zahl entspricht der reellen Zahl mal 10 hoch dem Exponenten.

    Kompakter formuliert, sieht diese Syntax so aus:

    [digits][.digits][(E|e)[(+|-)]digits]

    Zum Beispiel:

    3.14

    2345.6789

    .333333333333333333

    6.02e23        // 6.02 × 10²³

    1.4738223E-32  // 1.4738223 × 10-32

    Trennzeichen in Zahlliteralen

    Sie können in Zahlliteralen Unterstriche verwenden, um lange Literale in besser lesbare Abschnitte zu unterteilen:

    let billion = 1_000_000_000;  // Unterstrich als Tausendertrennzeichen.

    let bytes = 0x89_AB_CD_EF;    // Als Byte-Trennzeichen.

    let bits = 0b0001_1101_0111;  // Als Halbbyte-Trennzeichen.

    let fraction = 0.123_456_789;  // Das funktioniert auch im Nachkommateil.

    Anfang 2020, als ich dieses Buch verfasste, waren Unterstriche in Zahlliteralen noch nicht formal als Teil von JavaScript standardisiert. Aber sie befinden sich in einer fortgeschrittenen Phase des Standardisierungsprozesses und werden von allen gängigen Browsern und von Node verstanden.

    3.2.3Arithmetik in JavaScript

    JavaScript-Programme rechnen mit Zahlen mittels der arithmetischen Operatoren, die JavaScript bereitstellt. Zu diesen Operatoren gehören + für Addition, - für Subtraktion, * für Multiplikation, / für Division und % für Modulo (Rest nach Division). In ES2016 kam ** für die Potenzierung hinzu. Vollständige Angaben zu diesen und weiteren Operatoren finden Sie in Kapitel 4.

    Neben diesen elementaren arithmetischen Operatoren unterstützt JavaScript komplexere mathematische Operationen mithilfe der Funktionen und Konstanten, die als Eigenschaften des Math-Objekts definiert sind:

    Math.pow(2,53)          // => 9007199254740992: 2 hoch 53.

    Math.round(.6)          // => 1.0: Auf die nächste ganze Zahl runden.

    Math.ceil(.6)            // => 1.0: Auf die nächste ganze Zahl aufrunden.

    Math.floor(.6)          // => 0.0: Auf die nächste ganze Zahl abrunden.

    Math.abs(-5)            // => 5: Absolutwert.

    Math.max(x,y,z)          // Das größte der Argumente ermitteln.

    Math.min(x,y,z)          // Das kleinste der Argumente ermitteln.

    Math.random()            // Pseudozufallszahl, für deren Wert 0 <= x < 1.0 gilt.

    Math.PI                  // π: Kreisumfang / Kreisdurchmesser.

    Math.E                  // e: Die Basis des natürlichen Logarithmus.

    Math.sqrt(3)            // => 3**0.5: Die Quadratwurzel von 3.

    Math.pow(3, 1/3)        // => 3**(1/3): Die Kubikwurzel von 3.

    Math.sin(0)              // Trigonometrie: auch Math.cos, Math.atan usw.

    Math.log(10)            // Natürlicher Logarithmus von 10.

    Math.log(100)/Math.LN10  // Logarithmus zur Basis 10 von 100.

    Math.log(512)/Math.LN2  // Logarithmus zur Basis 2 von 512.

    Math.exp(3)              // Math.E hoch 3.

    ES6 definiert weitere Funktionen auf dem Math-Objekt:

    Math.cbrt(27)    // => 3: Kubikwurzel.

    Math.hypot(3, 4) // => 5: Quadratwurzel der Summe der Quadrate aller Argumente.

    Math.log10(100)  // => 2: Logarithmus zur Basis 10.

    Math.log2(1024)  // => 10: Logarithmus zur Basis 2.

    Math.log1p(x)    // Natürlicher Logarithmus von (1+x), genau für sehr kleine x.

    Math.expm1(x)    // Math.exp(x)-1, die Umkehrung von Math.log1p().

    Math.sign(x)    // -1, 0 oder 1 für Argumente <, == oder > 0.

    Math.imul(2,3)  // => 6: Optimierte Multiplikation von 32-Bit-Ganzzahlen.

    Math.clz32(0xf)  // => 28: Anzahl der führenden Nullbits in einer 32-Bit-Ganzzahl.

    Math.trunc(3.9)  // => 3: Konvertierung in eine Ganzzahl, indem der Nachkommateil

    // abgeschnitten wird.

    Math.fround(x)  // Auf die nächste 32-Bit-Gleitkommazahl runden.

    Math.sinh(x)    // Hyperbolischer Sinus. Auch Math.cosh(), Math.tanh().

    Math.asinh(x)    // Hyperbolischer Arkussinus. Auch Math.acosh(), Math.atanh().

    In JavaScript lösen arithmetische Operationen keine Fehler aus, wenn es zu Wertüberläufen, -unterläufen oder einer Division durch null kommt. Ist das Ergebnis einer numerischen Operation größer als die größte darstellbare Zahl (Überlauf), ist das Ergebnis ein spezieller Wert für unendlich, den JavaScript als Infinity ausgibt. Analog ergibt sich eine negative Unendlichkeit -Infinity, wenn der absolute Betrag (also der vorzeichenlose Wert) eines negativen Werts größer wird als der absolute Betrag der größten darstellbaren negativen Zahl. Unendliche Werte verhalten sich wie erwartet: Additions-, Subtraktions-, Multiplikations- und Divisionsoperationen auf einem unendlichen Wert liefern als Ergebnis wieder einen unendlichen Wert (gegebenenfalls mit umgekehrtem Vorzeichen).

    Ein Unterlauf tritt ein, wenn das Ergebnis einer numerischen Operation näher an null liegt als die kleinste darstellbare Zahl. In diesem Fall liefert JavaScript 0 zurück. Tritt der Unterlauf bei einer negativen Zahl auf, liefert JavaScript einen speziellen Wert zurück, der als negative Null bezeichnet wird. Dieser Wert ist beinahe vollständig mit dem gewöhnlichen Nullwert identisch, und JavaScript-Programmierer müssen ihn nur äußerst selten gesondert behandeln.

    Eine Division durch null löst in JavaScript keinen Fehler aus – sie liefert einfach unendlich oder negativ unendlich zurück. Es gibt allerdings eine Ausnahme: Null geteilt durch null hat keinen wohldefinierten Wert – das Ergebnis dieser Operation ist ein spezieller »Keine-Zahl«-Wert, der als NaN (kurz für Not-a-Number) ausgegeben wird. NaN ist auch das Ergebnis, wenn Sie versuchen, unendlich durch unendlich zu teilen, die Quadratwurzel einer negativen Zahl zu ermitteln oder arithmetische Operatoren auf nicht numerischen Operanden zu nutzen, die sich nicht in Zahlen umwandeln lassen.

    JavaScript definiert die globalen Konstanten Infinity und NaN so, dass sie den positiven Unendlichkeits- bzw. den Not-a-Number-Wert enthalten, und diese Werte sind auch als Eigenschaften des Number-Objekts verfügbar:

    Infinity                    // Eine positive Zahl, die zu groß ist,

    // um sie darzustellen.

    Number.POSITIVE_INFINITY    // Der gleiche Wert.

    1/0                        // => Infinity.

    Number.MAX_VALUE * 2        // => Infinity; Überlauf.

    -Infinity                  // Eine negative Zahl, die zu groß ist,

    // um sie darzustellen.

    Number.NEGATIVE_INFINITY    // Der gleiche Wert.

    -1/0                        // => -Infinity.

    -Number.MAX_VALUE * 2      // => -Infinity.

    NaN                        // Der Not-a-Number-Wert.

    Number.NaN                  // Der gleiche Wert, anders geschrieben.

    0/0                        // => NaN.

    Infinity/Infinity       

    Gefällt Ihnen die Vorschau?
    Seite 1 von 1