Jährlich erhält die ECMAScript-Spezifikation ein Update. Zuletzt am umfassendsten war 2015 der Sprung von ECMAScript 5 zu ECMAScript 6. Im Vergleich dazu sind die in ECMAScript 2021 zu erwartenden Neuerungen zwar klein, allerdings trotzdem einen genaueren Blick wert.
String replaceAll()
Aktuell gibt es keinen anderen Weg, alle Instanzen eines Substrings zu ersetzen, als über die etwas hacky Kombination der Methoden .split()
und .join()
oder über replace()
in Kombination mit einer sogenannten globalen Regular Expression (/regexp/g).
const snow = '❄️+☃️+❄️+❆';
const snowWithPenguins = snow.replace(/\+/g, '🐧');
console.log(snowWithPenguins); //❄️🐧☃️🐧❄️🐧❆
Die neue replaceAll()
-Methode in ECMAScript 2021 macht die Verwendung einer Regex obsolet:
const snow = '❄️+☃️+❄️+❆';
const snowWithPenguins = snow.replaceAll('+', '🐧');
console.log(snowWithPenguins); //❄️🐧☃️🐧❄️🐧❆
Ein weiteres Beispiel zur Verdeutlichung:
const cuteAnimal = "I love Penguins. Penguins are adorable, especially when they are fishing.";
let newCuteAnimal = cuteAnimal.replaceAll("Penguin", "Bear");
console.log(newCuteAnimal); //I love Bears. Bears are adorable, especially when they are fishing.
Zudem bringt die neue replaceAll()
-Methode einen kleinen Performanzzuwachs mit sich, weil anstelle eines Regular-Expression-Abgleichs auf String-Comparison zurückgegriffen wird.
Promise.any()
Ähnlich wie andere Promise-Methoden iteriert Promise.any() über eine Iterable von Promise-Objekten. Anders als Promise.all()
stoppt Promise.any()
nicht sobald eine der Promises nicht erfüllt wird, sondern durchläuft den Array, bis eine der Promises erfüllt wird. Ist das der Fall, gibt die Promise.any()
-Methode den Wert eben der ersten erfüllten Promise zurück, die anderen Promises werden nicht überprüft. Wird keine der Promises im Array erfüllt, wird der Output von Promise.any()
mit einem Aggregate-Error-Objekt abgelehnt.
const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 300, 'not so quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const promises = [promise1, promise2, promise3];
Promise.any(promises).then((value) => console.log(value));
// Expected output: "quick"
Promise.any()
ist nützlich, um zu überprüfen, ob eine Iterable (ein Array) von Promises zumindest eine Promise enthält, die erfüllt wird. Die Methode unterscheidet sich insofern von promise.race(), als dass nicht der Wert der ersten ausgeführten Promise, unabhängig davon, ob sie erfüllt oder abgelehnt wird, zurückgegeben wird, sondern die erste, die erfüllt wird. Von promise.all()
unterscheidet sie sich in sofern, dass nicht alle Promises in einer Iterablen überprüft und deren Values – sofern alle erfüllt – in einem Array ausgegeben werden.
tldr: Promise.any()
nimmt eine Iterable von Promise-Objekten und löst auf, wenn eine der Promises auflöst. Sie gibt eine einzelne Promise zurück – und zwar die erste, die aufgelöst wird, mit dem Wert aus dieser Promise.
Use-Case: Promise.any()
können Entwickler verwenden, wenn in einer Anwendung mehrere asynchrone Berechnungen ausgeführt werden und lediglich die erste erfolgreiche interessant ist. Vorstellbar ist das wie ein Wettlauf, bei dem der Gewinner – die schnellste Kalkulation – verwendet wird:
const myFetch = url => setTimeout(() => fetch(url), Math.floor(Math.random() * 4000));
const promises = [
myFetch('/endpoint-1'),
myFetch('/endpoint-2'),
myFetch('/endpoint-3'),
];
// Example using .then .catch
Promise.any(promises) // Any of the promises fullfilled.
.then(console.log) // e.g. '4'
.catch(console.error); //All of the promises were rejected.
// Example using async-await
try {
const first = await Promise.any(promises); // Any of the promises fullfilled.
console.log(first);
}catch (error) { // All of the promises were rejected
console.log(error);
}
Numerische Separatoren
Dieses neue Feature dient der besseren Lesbarkeit numerischer Literale.
Ein Unterstrich _ kann ab ES 2021 als Trennzeichen zwischen Zifferngruppen verwendet werden. Die Separatoren können theoretisch an beliebiger Stelle in beliebiger Anzahl verwendet werden – dass es ratsam ist, hier nach einem gewissen System vorzugehen, versteht sich wohl von selbst.
const twoBillion = 2000000000;
const twoBillionWithSeparators = 2_000_000_000;
const twoBillionAndALittleMore = 1_000_ooo_000.999_999;
Logical Assignment Operator
Der neue Logical Assignment Operator kombiniert sogenannte Logik-Operatoren – AND &&, OR || und Nullzusammenfügungsoperator ?? mit Assignment Expressions =, was zu einer geringfügig kürzeren Syntax führt. Details und Code-Beispiele könnt ihr in diesem Tooltipp nachlesen.
WeakRef
Objekte sind in JavaScript per Default stark referenziert. Das bedeutet, dass referenzierte Objekte nicht speicherbereinigt, sondern im Speicher gehalten werden.
let a, b;
a = b = document.querySelector('.refClass')
a = undefined
// ... GarbageCollecting...
// b is still referenced to the DOM-object .refClass
In einem Szenario, in dem Objekte nicht unendlich im Speicher gehalten werden sollen, können mit ES 2021 sogenannte Weak References verwendet werden, um Caches oder Mappings zum Beispiel auf sehr große Objekte zu implementieren. WeakRef bewirkt, dass sie, wenn sie nicht verwendet werden, aus dem Speicher bereinigt werden und bei Bedarf neu aus dem Cache erzeugt werden können.
Erzeugt wird eine solche schwache Referenz über new WeakRef
. Der Zugriff auf das Objekt erfolgt über die Methode .deref()
.
const example = new WeakRef(document.querySelector('.refClass'));
const element = example.deref();
Wer die Weiterentwicklung der ECMAScript-Spezifikation bis Juni im Auge behalten möchte, findet auf GitHub das Proposals-Repository.
Dass es keine andere Möglichkeit außer Regex zum Austauschen gibt, stimmt nicht ganz. Mit ‚text‘.split(‚abc‘).join(‚xyz‘) geht es auch.
true. danke für den hinweis!