Po opisaniu ES6 i ES7 przyszedł czas na ES8. Sprawdźmy, co nowego ES8 wniosło do świata frontendu!

padStart i padEnd

W ES8 dodano nowe metody dla Stringów – padStart() i padEnd(). Obydwie pozwalają na uzupełnianie stringów pustymi miejscami lub innymi stringami do określonego miejsca.

Zacznijmy od padStart. Funkcja ta dodaje puste spacje lub string przed oryginalnym stringiem:

let a = ‘asd’; // ”asd”

a.padStart(5) // “  asd” <- string ma 3 znaki, więc funkcja wstawiła 5-3=2 puste miejsca
a.padStart(10) // “       asd” <- 7 spacji
a.padStart(1) // “asd” <- liczba w funkcji jest mniejsza niż liczba znaków, więc nic nie wstawiono
a.padStart(3) // “asd” <- to samo co wyżej

A teraz parę przykładów ze wstawianiem stringów zamiast spacji:

a.padStart(3, ‘wsad’) // “asd”
a.padStart(7, ‘wsad’) // “wsadasd” <- Dodało 4 znaki przed naszym stringiem
a.padStart(4, ‘wsad’) // “wasd” <- nasz string ma 3 znaki, podana jest liczba 4, więc można wstawić 1 znak, więc wstawiono jeden znak z podanego w funkcji stringa.
a.padStart(5, ‘wsad’) // “wsasd” <- analogicznie, 2 znaki
a.padStart(10, ‘wsad’) // “wsadwsaasd” <- 10 znaków - 3 znaki oryginalnego stringa = 7 wolnych, dlatego podany string jest dodawany wielokrotnie aż do podanej liczby (10)

Analogicznie działa padEnd, jedynie dodaje nie na początku, a na końcu stringa:

a.padEnd(1) // “asd”
a.padEnd(3) // “asd”
a.padEnd(5) // “asd  ”
a.padEnd(10) // “asd       ”

Analogicznie do padStart, działa padEnd ze stringami:

a.padEnd(1, ‘wsad’) // “asd”
a.padEnd(3, ‘wsad’) // “asd”
a.padEnd(5, ‘wsad’) // “asdws”
a.padEnd(10, ‘wsad’) // “asdwsadwsa”

Object.values()

Funkcja ta zwraca tablicę ze wszystkimi wartościami z podanej tablicy lub obiektu:

const a = {name: ‘Dawid’, surname: ‘Kozak’};
const b = [‘Angular’, ‘React’, ‘Vue’];
Object.values(a); // [‘Dawid’, ‘Kozak’]
Object.values(b); //  [‘Angular’, ‘React’, ‘Vue’]

Object.entries()

Podobna funkcja do poprzedniej, która zwraca pary [klucz, wartość] z podanego obiektu lub pary [index, wartość] dla tablic:

const a = {name: ‘Dawid’, surname: ‘Kozak’};
const b = [‘Angular’, ‘React’, ‘Vue’];
Object.entries(a); // [[‘name’, ‘Dawid’], [‘surname’: ‘Kozak’]]
Object.entries(b); //  [[‘0’, ‘Angular’], [‘1’, ‘React’], [‘2’, ‘Vue’]]

Object.getOwnPropertyDescriptors()

Obiekty mają właściwości. Te właściwości to nie tylko klucz i wartość, ale też tak zwany deskryptor. Deskryptory pozwalają uzyskać więcej informacji o właściwości w obiekcie.

Deskryptor właściwości jest obiektem zawierającym poniższe atrybuty:

  • value – wartość związana z odpowiadającą właściwością
  • writable – jeżeli jest równa true, to odpowiadająca wartość właściwości może być zmieniona
  • get – funkcja, która zwraca getter dla odpowiadającej właściwości lub undefined, jeżeli getter nie występuje
  • set – funkcja, która zwraca setter dla odpowiadającej właściwości lub undefined, jeżeli setter nie występuje
  • configurable – jeżeli true odpowiadająca wartość właściwości może być zmieniona (również ich rodzaj – z właściwości danych na właściwość funkcji dostępowych i odwrotnie) oraz usunięta z odpowiadającego obiektu.
  • enumerable – jeżeli true odpowiadająca wartość właściwości będzie dostępna podczas iteracji po właściwościach odpowiadającego obiektu.

Funkcja getOwnPropertyDescriptors pozwala uzyskać deskryptor wskazanego obiektu.

let obiekt, deskryptor;

obiekt = { get asd() { return 17; } };
deskryptor = Object.getOwnPropertyDescriptor(o, 'asd'); // { configurable: true, enumerable: true, get: /*the getter function*/, set: undefined }

obiekt = { wsad: 42 };
deskryptor = Object.getOwnPropertyDescriptor(o,’wsad’); // { configurable: true, enumerable: true, value: 42, writable: true }

Końcowe przecinki

Pozwolono w końcu używać przecinków na końcu deklaracji, czy wywołania funkcji. Ujednolica to kod:

const funkcja = (zmienna, zmienna2,) => {  //...}
funkcja('asd', 'wsad',)

Async/Await

Temat Aysnc/Await jest bardzo duży, tak więc szczegółowo opisany tutaj – https://rwbit.pl/async-await/. Na teraz warto wiedzieć, że Acyns/Await powstał jako wyższy poziom abstrakcji nad promisami. Tak, Async/Await jest zbudowane z promisów.

const zrobCos = async () => {
  console.log('start');
  const zmienna = await funkcjaAsynchroniczna();
  console.log(zmienna);
  console.log('koniec');
}

Tak wygląda podstawowe użycie Async/Await. Przy deklaracji funkcji dodajemy słowo kluczowe “async”, dzięki czemu JS wie, że tutaj wystąpi funkcja asynchroniczna. W kodzie, kiedy mamy wywołanie takiej funkcji asynchronicznej, używamy słowa kluczowego “await”, które sprawia, że kod JS tak jakby poczeka w tym miejscu, aż funkcja asynchroniczna wykona swoje zadanie i zwróci odpowiedź. Dopiero po otrzymaniu odpowiedzi, kod wróci do normalnego wykonywania się.

Rozwiązuje to sporo problemów oraz niejasności w tworzeniu kodu i używaniu asynchroniczności. Sprawia też, że kod jest o wiele czytelniejszy – widać od razu, gdzie są funkcje asynchroniczne.

Shared memory and atomics

WebWorkery pozwalają na tworzenie kodu wielowątkowego. Przed ES8 kontakt między webworkerami odbywał się przez eventy, jednak od ES8 można stworzyć SharedMemory, używając SharedArrayBuffer.

Aby uniknąć wyścigów, stworzono Atomics. Dzięki nim wiemy, że kiedy odczytujemy dane z SharedMemory, wszystkie operacje zapisu do tej pamięci współdzielonej są zakończone.

Temat jest na tyle szeroki, że również opiszę go w oddzielnym wpisie, który tutaj podlinkuję.

Podsumowanie

To wszystkie nowości z ES8. Pierwszy raz pojawiły się tematy wymagające osobnego wpisu, mam nadzieję, że nie przeszkadza Ci to. Robię to, aby lepiej i szerzej opisać te zagadnienia, zamiast traktować je po macoszemu.  Te tematy pojawią się już niedługo :)

Daj znać w komentarzu, których nowości z ES8 używasz najczęściej.