Фічі JavaScript, про які ви могли не знати. State of JavaScript 2023

Фічі JavaScript, про які ви могли не знати. State of JavaScript 2023
~9 хв
22 серп 2024
Валерій Стрілець

State of JavaScript 2023, один з найочікуваніших щорічних звітів про розвиток JavaScript, опублікував оновлену інформацію про актуальні фічі. У цій статті ми детально розглянемо рейтинг фіч, що використовуються найбільше, а також приклади їх застосування.

Фічі синтаксису

Оператор об’єднання з null

1 місце. Nullish Coalescing. Проголосувало 80% людей.

Оператор об’єднання з null ?? дозволяє легко задавати значення, якщо змінна дорівнює null або undefined, на відміну від оператора ||, який оперує тільки falsy значеннями. Це зручно при роботі з необов'язковими значеннями та для уникнення помилок.

const unknown1 = null;
const foo = unknown1 ?? 'default';
console.log(foo); // 'default'

const unknown2 = 0;
const bar = unknown2 ?? 42;
console.log(bar); // 0

Динамічний імпорт

2 місце. Dynamic Import. Проголосувало 62% людей.

Динамічний імпорт дозволяє завантажувати модулі асинхронно, коли вони дійсно потрібні. Це допомагає оптимізувати перфоманс вашого додатку, завантажуючи код лише за потребою, що зменшує початковий розмір бандлу.

let myModule;

if (typeof window === "undefined") {
  myModule = await import("module-used-on-server");
} else {
  myModule = await import("module-used-in-browser");
}

Приватні поля

3 місце. Private Fields. Проголосувало 35% людей.

Для створення приватного поля в класах, потрібно додати префікс # до назви і це дозволить створювати властивості, доступ до яких можливий лише всередині класу. Це забезпечує кращу інкапсуляцію даних та захист від доступу ззовні класу.

class MyClass {
  #privateField = 10;

  getPrivateField() {
    return this.#privateField;
  }
}

const instance = new MyClass();
console.log(instance.getPrivateField()); // 10
console.log(instance.#privateField);
// SyntaxError: Private field '#privateField' must be declared in an enclosing class

Майте на увазі, що в DevTools приватні поля все ще доступні для зручного дебагінгу.

Логічне присвоєння

4 місце. Logical Assignment. Проголосував 31% людей.

Логічні оператори присвоєння &&=, ||= та ??= дозволяють скоротити код, комбінуючи логічні оператори з присвоєнням. Це робить код простішим та зрозумілішим.

let settings;

function emptyIfNotExist() {
  settings ||= {};
  
  // Замість
  // if (!settings) {
  //   settings = {};
  // }
}

function removeIfExist() {
  settings &&= null;
  
  // Замість
  // if (settings) {
  //   settings = null;
  // }
}

function setNullIfNotDefined() {
  settings ??= null;
  
  // Замість
  // if (settings === null || settings === undefined) {
  //   settings = null;
  // }
}

Простими словами, до одного з операторів &&, || або ?? можна додати в кінець =, тим самим записавши нове значення в змінну, що перевіряється.

Граматика Hashbang (Shebang)

5 місце. Hashbang Grammar. Проголосувало 22% людей.

Hashbang #! дозволяє вказати інтерпретатор скрипту безпосередньо в коді JavaScript, що корисно для написання скриптів, які виконуються у середовищі Node.js.

#!/usr/bin/env node

console.log('Hello, world!');

Детальніше про Hashbang на Wiki.

error.cause

6 місце. Проголосувало 16% людей.

Ця функція дозволяє вказувати причину для помилок, що полегшує відстеження ланцюга викликів помилок та робить дебагінг більш простим та інформативним.

try {
  connectToDatabase();
} catch (err) {
  throw new Error('Connecting to database failed.', { cause: err });
}

Фічі string

string.replaceAll()

1 місце. Проголосувало 73% людей.

Метод replaceAll() дозволяє замінювати всі збіги всередині рядка. Це значно спрощує операції пошуку та заміни в тексті.

const str = 'foo bar foo';
const newStr = str.replaceAll('foo', 'baz');
console.log(newStr); // 'baz bar baz'

string.matchAll()

2 місце. Проголосувало 44% людей.

Метод matchAll() повертає ітератор, що містить всі збіги регулярного виразу в рядку. Це корисно для обробки складних шаблонів та отримання всіх результатів одночасно.

const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';
const array = [...str.matchAll(regexp)];

console.log(array);
// Output: Array [
//   ['test1', 'e', 'st1', '1'],
//   ['test2', 'e', 'st2', '2'],
// ]

Індекси відповідності Regexp

3 місце. Regexp Match Indices. Проголосувало 24% людей.

Індекси відповідності регулярних виразів додаються за допомогою d прапора та дозволяють отримати позиції всіх збігів, що допомагає більш точно обробляти текст.

const str1 = "foo bar foo";

const regex1 = /foo/dg;

console.log(regex1.hasIndices); // true

console.log(regex1.exec(str1).indices[0]); // [0, 3]
console.log(regex1.exec(str1).indices[0]); // [8, 11]

const str2 = "foo bar foo";

const regex2 = /foo/;

console.log(regex2.hasIndices); // false

console.log(regex2.exec(str2).indices); // undefined

Фічі array

array.findLast()

1 місце. Проголосувало 30% людей.

Метод findLast() працює так само, як і find, але починає пошук з кінця масиву та повертає останній елемент, який задовольняє умову.

const arr = [1, 2, 3, 4, 5];
const found = arr.findLast(element => element % 2 === 0);
console.log(found); // 4

array.toSorted(), array.toReversed() та array.toSpliced()

2, 3 та 4 місце. Проголосувало 30%, 26% та 16% людей відповідно.

Ці три методи є стовідсотковими копіями своїх оригінальних методів sort, reverse та splice з єдиною відмінністю - вони не мутують оригінальний масив, а створюють новий.

const arr = [3, 1, 4, 1, 5];
const sorted = arr.toSorted();
console.log(sorted); // [1, 1, 3, 4, 5]
console.log(arr); // [3, 1, 4, 1, 5]

array.with()

5 місце. Проголосувало 11% людей.

Метод with() повертає новий масив з одним зміненим елементом, що дозволяє легко оновлювати дані без мутації оригінального масиву.

const arr = [1, 2, 3, 4, 5];
console.log(arr.with(2, 6)); // [1, 2, 6, 4, 5]

Фічі асинхронності

Top-level await

1 місце. Проголосувало 74% людей.

Оператор await на верхньому рівні дозволяє використовувати асинхронний код безпосередньо в модулях без обгортки в асинхронні функції, що робить код більш зрозумілим та прямолінійним.

// top-level-await.mjs
const data = await fetchData();
console.log(data);

Promise.any()

2 місце. Проголосувало 43% людей.

Метод Promise.any() повертає перший успішно виконаний проміс з масиву. Це корисно для сценаріїв, де достатньо першого успішного результату, ігноруючи всі відхилені проміси.

const promise1 = Promise.reject('Error 1');
const promise2 = new Promise(
  (resolve) => setTimeout(resolve, 100, 'Result 2'),
);
const promise3 = new Promise(
  (resolve) => setTimeout(resolve, 200, 'Result 3'),
);

const value = await Promise.any([promise1, promise2, promise3]);

console.log(value); // 'Result 2'

Promise.allSettled()

3 місце. Проголосувало 43% людей.

Метод Promise.allSettled() повертає усі результати промісів, незалежно від того, були вони успішні чи ні. Це дозволяє обробляти всі завершення промісів одночасно, не перериваючи роботу через помилки.

const promise1 = Promise.resolve('Result 1');
const promise2 = Promise.reject('Error 2');
const promise3 = Promise.resolve('Result 3');

const results = await Promise.allSettled([promise1, promise2, promise3])

results.forEach((result) => {
  console.log(result.status, result.value || result.reason)
});

// fulfilled Result 1
// rejected Error 2
// fulfilled Result 3

Статистика взята зі State Of JS Features.

поглиблюй свої знання з wannabe school
поглиблюй свої знання з wannabe school
поглиблюй свої знання з wannabe school
поглиблюй свої знання з wannabe school
Свідоме навчання
від практикуючих IT-працівників
Елемент паралаксу
Елемент паралаксу