AJ 1.6 Avancerad funktionalitet i ES.Next
Table of contents
ECMAScript
JavaScript är en implementation av ECMAScript. ECMAScript är en teknisk standard som beskriver hur andra språk ska fungera, som ett blueprint. Det går alltså att göra egna varianter av ECMAScript än JavaScript (ex ActionScript), men de måste följa ECMAScript.
Dokumentationen kan vara krånglig att läsa, eftersom det mer är en blueprint än en konkret dokumentation av språket.
(Läs mer om ECMAScript här)
Vad är ES.Next?
ES.Next är en dynamisk term, som syftar på nästa version av ECMAScript. De är väldigt noga med att allting hela tiden ska vara bakåtkompatibelt, så det tar lång tid att testa och införa nya features.
Utvecklingsprocessen i TC39
TC39 är ECMA:s tekniska kommitté som går igenom alla proposals/förslag som kommer in.
- En ny feature börjar som en idé från en person, vem som helst kan lägga in en.
- Den som lägger in en idé skriver på ett kontrakt med ECMA kommittén
- Sen följer en process i fyra delar (sk maturety stages), det kallas att featuren mognar
De fyra (fem) stegen
- Steg 0 - Strawman
- idéer för nya tillägg
- input till specifikationen
- Steg 1 - Proposal
- formell ansökan för tillägg
- beskriv lösningen
- identifiera eventuella svårigheter
- Steg 2 - Draft
- en version med det som ska in i specifikatioen
- beskriv syntax och semantik formellt i specifikationens språk
- Steg 3 - Candidate
- feedback och implementation
- Steg 4 - Finished
- förslaget klart att läggas till i den formella standarden
2021 features
Ny funktionalitet som har godkänts av TC39 och implementerats i ECMAScript 2021.
String.prototype.replaceAll()
Promise.any()
- Numeric separators
- Logical assignment operators
WeakRef
ochFinalizationRegistry
String.prototype.replaceAll()
Ersätt alla förekomster av en given sträng (första argumentet) med en annan given sträng (andra argumentet).
Exempel1
const myString = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';
console.log(myString.replaceAll('dog', 'monkey'));
// prints: 'The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?'
Promise.any()
Tar en array av Promise
-objekt och itererar över dem. Så fort någon av de givna objekten ‘lyckas’ (fullfill), så returneras värdet från det promiset. Om inget av objekten lyckas (alla rejectas), så returnas en error.2
Promise.any()
resolvas alltså alltid med värdet från det första promiset som lyckas, även om något annat av promise-objekten misslyckas/rejectas.
Exempel3
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const promises = [promise1, promise2, promise3];
Promise.any(promises).then((value) => console.log(value));
// prints: 'quick'
Numeric separators
För att öka läsbarheten kan underscores (_
) användas som numeriska separatorer. Fungerar med vanliga tal, binära tal och hex-tal.
Exempel4
// separatorer i decimala tal
1_000_000_000_000
1_050.95
// separatorer i binära tal
0b1010_0001_1000_0101
// separatorer i hex tal
0xA0_B0_C0
Logical assignment operators5
Binära operatorer med tilldelningsfunktionalitet.
&&=
- om vänstra sidan är truthy så tilldelas den värden på högra sidan||=
- om vänstra sidan är falsy, så tilldelas den värdet på högra sidan??=
- om vänstra sidan är nullish eller undefined, så tilldelas värdet på högra sidan
Exempel
let x = 1;
let y = 2;
x &&= y; // om x är truthy blir den y
x ||= y; // om x är falsy blir den y
x ??= y; // om x är nullsih/undefined blir den y
WeakRef
och FinalizationRegistry
Generellt så är referenser till objekt i JS strong, vilket betyder att så länge det finns en referens till ett objekt så kommer objektet att finnas kvar och ta upp minne. WeakRef
skapar en weak (svag) referens, som inte håller kvar objektet det referear till i minnet.6
FinalizationRegistry
används ihop med WeakRef
, och låter oss registrera en callback som kan köras när objektet vi refererar till försvinner ur minnet.7 8
(OBS! Enligt MDN bör dessa bara användas i undantagsfall9)
2022 features
Några features som kommer att komma 2022.10
Class fields
Det här förslaget innehåller flera delar. Jag går igenom några i korthet nedan.
Definiera variabler i klasser
Möjlighet att definiera variabler direkt i toppen av klassen, istället för i constructorn (likt hur det fungerar i Angular).11
// define fields in constructor
class SomeClass {
constructor() {
this.value = 0;
this.content = 'Hello World!';
}
// ...
}
// define fields in top level of class
class SomeClass {
value = 0;
content = 'Hello World!';
//...
}
Privata metoder och åtkomster i klasser
Syntax för att göra metoder, setter/getters och variabler i klasser privata på “riktigt” (inte bara hinta om att de borde hållas privata med _
), genom att sätta #
före.11 12
// name is not really private (but should be kept private)
class Cat {
_name = 'Bosse';
get _name() {
return this._name;
}
}
let myCat = new Cat();
console.log(myCat._name); // prints 'Bosse'
// name is truly private and can only be accessed from inside class
class Dog (
#name = 'Rei';
get #name() {
return this.#name;
}
)
let myDog = new Dog();
console.log(myDog.name); // undefined
Privata metoder fungerar på liknande sätt, med #
. (Intressant länk här om varför inte keywordet private
används istället, som i andra språk)
Variabler utan värde
Möjlighet att definiera varibler i klasser utan ett initialt värde (också likt hur det fungerar i Angular). Värdet blir då undefined
tills det evenutellt tilldeles ett annat.13
class Cat {
name;
//...
}
Top-level await
Just nu så är await
bara tillgängligt inom async
-funktioner. Med top-level await
, så kan moduler agera som stora async
-funktioner, de kan awaita resources/data, vilken kan få andra moduler som importerar dem att också vänta/awaita. Problemet just nu är att en modul kan importera en annan modul innan den första modulens async
-funktioner är resolvade. Outputen kan då bli undefined
eller något annat knas.14