Zum Hauptinhalt springen

Promise-Kombinatoren

· 4 Minuten Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Seit der Einführung von Promises in ES2015 unterstützt JavaScript genau zwei Promise-Kombinatoren: die statischen Methoden Promise.all und Promise.race.

Zwei neue Vorschläge befinden sich derzeit im Standardisierungsprozess: Promise.allSettled und Promise.any. Mit diesen Ergänzungen gibt es insgesamt vier Promise-Kombinatoren in JavaScript, die jeweils unterschiedliche Anwendungsfälle ermöglichen.

`Array.prototype.flat` und `Array.prototype.flatMap`

· 2 Minuten Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Array.prototype.flat

Das Array in diesem Beispiel ist mehrere Ebenen tief: Es enthält ein Array, das wiederum ein weiteres Array enthält.

const array = [1, [2, [3]]];
// ^^^^^^^^^^^^^ äußeres Array
// ^^^^^^^^ inneres Array
// ^^^ innerstes Array

Array#flat gibt eine reduzierte Version eines gegebenen Arrays zurück.

array.flat();
// → [1, 2, [3]]

// …entspricht folgendem:
array.flat(1);
// → [1, 2, [3]]

Die Standardtiefe ist 1, aber Sie können jede Zahl übergeben, um rekursiv bis zu dieser Tiefe zu reduzieren. Um rekursiv zu reduzieren, bis das Ergebnis keine verschachtelten Arrays mehr enthält, geben wir Infinity weiter.

// Rekursiv reduzieren, bis das Array keine verschachtelten Arrays mehr enthält:
array.flat(Infinity);
// → [1, 2, 3]

Warum heißt diese Methode Array.prototype.flat und nicht Array.prototype.flatten? Lesen Sie unseren Bericht zu #SmooshGate, um es herauszufinden!

Array.prototype.flatMap

Hier ist ein weiteres Beispiel. Wir haben eine Funktion duplicate, die einen Wert nimmt und ein Array zurückgibt, das diesen Wert zweimal enthält. Wenn wir duplicate auf jeden Wert in einem Array anwenden, erhalten wir ein verschachteltes Array.

const duplicate = (x) => [x, x];

[2, 3, 4].map(duplicate);
// → [[2, 2], [3, 3], [4, 4]]

Sie können dann flat auf das Ergebnis aufrufen, um das Array zu reduzieren:

[2, 3, 4].map(duplicate).flat(); // 🐌
// → [2, 2, 3, 3, 4, 4]

Da dieses Muster in der funktionalen Programmierung so häufig vorkommt, gibt es jetzt eine eigene Methode flatMap dafür.

[2, 3, 4].flatMap(duplicate); // 🚀
// → [2, 2, 3, 3, 4, 4]

flatMap ist ein wenig effizienter, als map gefolgt von einem separaten flat zu verwenden.

Interessiert an Anwendungsfällen für flatMap? Schauen Sie sich Axel Rauschmayers Erklärung an.

Unterstützung für Array#{flat,flatMap}

Numerische Separatoren

· 2 Minuten Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Große numerische Literale sind für das menschliche Auge schwer schnell zu erkennen, besonders wenn viele sich wiederholende Ziffern vorhanden sind:

1000000000000
1019436871.42

Um die Lesbarkeit zu verbessern, ermöglicht eine neue JavaScript-Sprachfunktion die Verwendung von Unterstrichen als Trennzeichen in numerischen Literalen. Somit kann das oben stehende nun so umgeschrieben werden, dass die Ziffern beispielsweise in Tausendergruppen zusammengefasst werden:

`String.prototype.matchAll`

· 3 Minuten Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Es ist üblich, denselben regulären Ausdruck wiederholt auf einen String anzuwenden, um alle Übereinstimmungen zu erhalten. Bis zu einem gewissen Grad ist dies heute bereits durch die Methode String#match möglich.

In diesem Beispiel finden wir alle Wörter, die nur aus hexadezimalen Ziffern bestehen, und protokollieren dann jede Übereinstimmung:

const string = 'Magische Hex-Zahlen: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
for (const match of string.match(regex)) {
console.log(match);
}

// Ausgabe:
//
// 'DEADBEEF'
// 'CAFE'

Dies gibt Ihnen jedoch nur die Substrings, die übereinstimmen. Normalerweise möchten Sie nicht nur die Substrings, sondern auch zusätzliche Informationen wie den Index jedes Substrings oder die Gruppen, die innerhalb jeder Übereinstimmung erfasst wurden.

Es ist bereits möglich, dies zu erreichen, indem man eine eigene Schleife schreibt und die Übereinstimmungsobjekte selbst verfolgt, aber das ist ein wenig lästig und nicht sehr bequem:

const string = 'Magische Hex-Zahlen: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
let match;
while (match = regex.exec(string)) {
console.log(match);
}

// Ausgabe:
//
// [ 'DEADBEEF', index: 19, input: 'Magische Hex-Zahlen: DEADBEEF CAFE' ]
// [ 'CAFE', index: 28, input: 'Magische Hex-Zahlen: DEADBEEF CAFE' ]

Die neue API String#matchAll macht dies einfacher als je zuvor: Sie können jetzt eine einfache for-of-Schleife schreiben, um alle Übereinstimmungsobjekte zu erhalten.

const string = 'Magische Hex-Zahlen: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
for (const match of string.matchAll(regex)) {
console.log(match);
}

// Ausgabe:
//
// [ 'DEADBEEF', index: 19, input: 'Magische Hex-Zahlen: DEADBEEF CAFE' ]
// [ 'CAFE', index: 28, input: 'Magische Hex-Zahlen: DEADBEEF CAFE' ]

String#matchAll ist besonders nützlich für reguläre Ausdrücke mit Gruppenerfassung. Es gibt Ihnen vollständige Informationen für jede einzelne Übereinstimmung, einschließlich der erfassten Gruppen.

const string = 'Lieblings-GitHub-Repos: tc39/ecma262 v8/v8.dev';
const regex = /\b(?<owner>[a-z0-9]+)\/(?<repo>[a-z0-9\.]+)\b/g;
for (const match of string.matchAll(regex)) {
console.log(`${match[0]} bei ${match.index} mit '${match.input}'`);
console.log(`→ Besitzer: ${match.groups.owner}`);
console.log(`→ Repo: ${match.groups.repo}`);
}

`Intl.ListFormat`

· 3 Minuten Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias)) und Frank Yung-Fong Tang

Moderne Webanwendungen verwenden oft Listen mit dynamischen Daten. Zum Beispiel könnte eine Fotoanzeige-App etwas wie das Folgende darstellen:

Dieses Foto beinhaltet Ada, Edith, und Grace.

Ein textbasiertes Spiel könnte eine andere Art von Liste haben:

Wähle deine Superkraft: Unsichtbarkeit, Psychokinese, oder Empathie.

Da jede Sprache unterschiedliche Listformatierungsgewohnheiten und Wörter hat, ist die Implementierung eines lokalisierten Listenformatierers nicht trivial. Dies erfordert nicht nur eine Liste aller Wörter (wie „und“ oder „oder“ in den obigen Beispielen) für jede unterstützte Sprache – zusätzlich müssen auch die genauen Formatierungsgewohnheiten für all diese Sprachen kodiert werden! Das Unicode CLDR stellt diese Daten bereit, aber um sie in JavaScript zu verwenden, müssen sie eingebettet und zusammen mit anderem Bibliothekscode ausgeliefert werden. Leider erhöht dies die Paketgröße solcher Bibliotheken, was sich negativ auf Ladezeiten, Parser-/Kompilierungskosten und Speicherverbrauch auswirkt.

Modul-Namespace-Exporte

· Eine Minute Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

In JavaScript-Modulen war es bereits möglich, die folgende Syntax zu verwenden:

import * as utils from './utils.mjs';

Es existierte jedoch keine symmetrische export-Syntax… bis jetzt:

export * as utils from './utils.mjs';

Dies ist gleichbedeutend mit dem Folgenden:

import * as utils from './utils.mjs';
export { utils };

Öffentliche und private Klassenfelder

· 4 Minuten Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Mehrere Vorschläge erweitern die bestehende JavaScript-Klassensyntax um neue Funktionen. Dieser Artikel erklärt die neue Syntax von öffentlichen Klassenfeldern in V8 v7.2 und Chrome 72 sowie die kommende Syntax von privaten Klassenfeldern.

Hier ist ein Codebeispiel, das eine Instanz einer Klasse namens IncreasingCounter erstellt:

const counter = new IncreasingCounter();
counter.value;
// protokolliert 'Den aktuellen Wert abrufen!'
// → 0
counter.increment();
counter.value;
// protokolliert 'Den aktuellen Wert abrufen!'
// → 1

Beachten Sie, dass der Zugriff auf value einen Code ausführt (d. h., er protokolliert eine Nachricht), bevor das Ergebnis zurückgegeben wird. Überlegen Sie sich nun, wie Sie diese Klasse in JavaScript implementieren würden? 🤔

ES2015-Klassensyntax

So könnte IncreasingCounter unter Verwendung der ES2015-Klassensyntax implementiert werden:

class IncreasingCounter {
constructor() {
this._count = 0;
}
get value() {
console.log('Den aktuellen Wert abrufen!');
return this._count;
}
increment() {
this._count++;
}
}

Die Klasse installiert den value-Getter und eine increment-Methode auf dem Prototyp. Interessanterweise hat die Klasse einen Konstruktor, der eine Instanzeigenschaft _count erstellt und ihren Standardwert auf 0 setzt. Derzeit verwenden wir oft das Unterstrichpräfix, um anzuzeigen, dass _count nicht direkt von Konsumenten der Klasse verwendet werden sollte, aber das ist nur eine Konvention; es ist keine wirklich „private“ Eigenschaft mit speziellen Semantiken, die von der Sprache durchgesetzt werden.

`Intl.RelativeTimeFormat`

· 5 Minuten Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Moderne Webanwendungen verwenden häufig Phrasen wie „gestern“, „vor 42 Sekunden“ oder „in 3 Monaten“ anstelle vollständiger Datumsangaben und Zeitstempel. Solche relativen Zeitformatierungswerte sind so gebräuchlich geworden, dass mehrere beliebte Bibliotheken Utility-Funktionen bereitstellen, die sie auf lokalisierte Weise formatieren. (Beispiele sind Moment.js, Globalize und date-fns.)

Gut geformtes `JSON.stringify`

· Eine Minute Lesezeit
Mathias Bynens ([@mathias](https://twitter.com/mathias))

JSON.stringify wurde zuvor so spezifiziert, dass es schlecht geformte Unicode-Zeichenketten zurückgibt, wenn die Eingabe einsame Surrogate enthält:

JSON.stringify('\uD800');
// → '"�"'

Der Vorschlag „Gut geformtes JSON.stringify ändert JSON.stringify so, dass es Escape-Sequenzen für einsame Surrogate ausgibt, wodurch seine Ausgabe gültiges Unicode wird (und in UTF-8 darstellbar ist):

JavaScript-Module

· 20 Minuten Lesezeit
Addy Osmani ([@addyosmani](https://twitter.com/addyosmani)) und Mathias Bynens ([@mathias](https://twitter.com/mathias))

JavaScript-Module werden jetzt in allen großen Browsern unterstützt!

Dieser Artikel erklärt, wie man JS-Module verwendet, wie man sie verantwortungsbewusst einsetzt und wie das Chrome-Team daran arbeitet, Module in Zukunft noch besser zu machen.

Was sind JS-Module?

JS-Module (auch bekannt als „ES-Module“ oder „ECMAScript-Module“) sind eine wichtige neue Funktion oder vielmehr eine Sammlung neuer Funktionen. Vielleicht haben Sie in der Vergangenheit ein benutzerdefiniertes JavaScript-Modulsystem verwendet. Vielleicht haben Sie CommonJS wie in Node.js verwendet, oder vielleicht AMD oder etwas anderes. All diese Modulsysteme haben eines gemeinsam: Sie ermöglichen es Ihnen, Dinge zu importieren und zu exportieren.