Zum Hauptinhalt springen

13 Posts getaggt mit "io19"

Alle Tags anzeigen

`Intl.NumberFormat`

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

Sie kennen möglicherweise bereits die Intl.NumberFormat-API, da sie seit einiger Zeit in modernen Umgebungen unterstützt wird.

In ihrer grundlegendsten Form ermöglicht Intl.NumberFormat das Erstellen einer wiederverwendbaren Formatierer-Instanz, die lokalisationsspezifische Zahlenformatierung unterstützt. Genau wie andere Intl.*Format-APIs unterstützt eine Formatierer-Instanz sowohl eine format- als auch eine formatToParts-Methode:

`globalThis`

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

Wenn Sie schon einmal JavaScript für die Verwendung in einem Webbrowser geschrieben haben, haben Sie möglicherweise window verwendet, um auf das globale this zuzugreifen. In Node.js haben Sie möglicherweise global verwendet. Wenn Sie Code geschrieben haben, der in beiden Umgebungen funktionieren muss, haben Sie möglicherweise festgestellt, welche von diesen verfügbar ist, und diese dann verwendet – aber die Liste der zu überprüfenden Bezeichner wächst mit der Anzahl der Umgebungen und Anwendungsfälle, die Sie unterstützen möchten. Das gerät schnell außer Kontrolle:

Schwache Verweise und Finalizer

· 10 Minuten Lesezeit
Sathya Gunasekaran ([@_gsathya](https://twitter.com/_gsathya)), Mathias Bynens ([@mathias](https://twitter.com/mathias)), Shu-yu Guo ([@_shu](https://twitter.com/_shu)), und Leszek Swirski ([@leszekswirski](https://twitter.com/leszekswirski))

Im Allgemeinen werden Referenzen auf Objekte in JavaScript stark gehalten, was bedeutet, dass das Objekt nicht vom Garbage Collector gesammelt wird, solange eine Referenz darauf existiert.

const ref = { x: 42, y: 51 };
// Solange Sie Zugriff auf `ref` (oder eine andere Referenz auf
// dasselbe Objekt) haben, wird das Objekt nicht vom Garbage Collector gesammelt.

Momentan sind WeakMaps und WeakSets die einzigen Möglichkeiten, ein Objekt in JavaScript schwach zu referenzieren: Das Hinzufügen eines Objekts als Schlüssel zu einer WeakMap oder einem WeakSet verhindert nicht, dass es vom Garbage Collector gesammelt wird.

const wm = new WeakMap();
{
const ref = {};
const metaData = 'foo';
wm.set(ref, metaData);
wm.get(ref);
// → metaData
}
// Wir haben in diesem Block keinen Zugriff mehr auf `ref`, daher kann es
// jetzt vom Garbage Collector gesammelt werden, obwohl es ein Schlüssel in `wm` ist, auf den wir noch zugreifen können.

Stabile `Array.prototype.sort`

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

Angenommen, Sie haben ein Array von Hunden, wobei jeder Hund einen Namen und eine Bewertung hat. (Falls dies wie ein seltsames Beispiel klingt, sollten Sie wissen, dass es ein Twitter-Konto gibt, das sich genau darauf spezialisiert hat… Fragen Sie nicht!)

// Beachten Sie, dass das Array nach `name` alphabetisch vorsortiert ist.
const doggos = [
{ name: 'Abby', rating: 12 },
{ name: 'Bandit', rating: 13 },
{ name: 'Choco', rating: 14 },
{ name: 'Daisy', rating: 12 },
{ name: 'Elmo', rating: 12 },
{ name: 'Falco', rating: 13 },
{ name: 'Ghost', rating: 14 },
];
// Sortieren Sie die Hunde nach `rating` in absteigender Reihenfolge.
// (Dies aktualisiert `doggos` direkt.)
doggos.sort((a, b) => b.rating - a.rating);

`Object.fromEntries`

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

Object.fromEntries ist eine nützliche Ergänzung zur eingebauten JavaScript-Bibliothek. Bevor erklärt wird, was es tut, hilft es, die bereits vorhandene API Object.entries zu verstehen.

Object.entries

Die Object.entries-API existiert schon seit einiger Zeit.

Für jedes Schlüssel-Wert-Paar in einem Objekt liefert Object.entries ein Array, bei dem das erste Element der Schlüssel und das zweite Element der Wert ist.

Object.entries ist besonders nützlich in Kombination mit for-of, da es ermöglicht, sehr elegant über alle Schlüssel-Wert-Paare in einem Objekt zu iterieren:

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

for (const [key, value] of entries) {
console.log(`Der Wert von ${key} ist ${value}.`);
}
// Ausgabe:
// Der Wert von x ist 42.
// Der Wert von y ist 50.

Leider gibt es keinen einfachen Weg, um aus dem Ergebnis von entries wieder ein äquivalentes Objekt zu erzeugen… bis jetzt!

Object.fromEntries

Die neue API Object.fromEntries führt das Umkehrverfahren von Object.entries durch. Dies erleichtert die Rekonstruktion eines Objekts basierend auf seinen Einträgen:

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

const result = Object.fromEntries(entries);
// → { x: 42, y: 50 }

Ein üblicher Anwendungsfall ist das Transformieren von Objekten. Dies können Sie jetzt tun, indem Sie über deren Einträge iterieren und dann Methoden für Arrays verwenden, die Ihnen möglicherweise schon bekannt sind:

const object = { x: 42, y: 50, abc: 9001 };
const result = Object.fromEntries(
Object.entries(object)
.filter(([ key, value ]) => key.length === 1)
.map(([ key, value ]) => [ key, value * 2 ])
);
// → { x: 84, y: 100 }

In diesem Beispiel filtern wir mit filter das Objekt, um nur Schlüssel der Länge 1 zu erhalten, das heißt, nur die Schlüssel x und y, nicht jedoch den Schlüssel abc. Wir verwenden dann map, um über die verbleibenden Einträge zu iterieren und ein aktualisiertes Schlüssel-Wert-Paar für jeden zurückzugeben. In diesem Beispiel verdoppeln wir jeden Wert, indem wir ihn mit 2 multiplizieren. Das Endergebnis ist ein neues Objekt mit nur den Eigenschaften x und y und den neuen Werten.

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.