Що нового в ES2022? 🤔
Tags: javascript, programming, tutorial, algorithms
Published: 2023-07-23 15:05:07

## 1. Метод .at() індексованих значень

Ця функція дозволяє нам читати елемент із заданим індексом. Він може приймати від’ємні індекси для читання елементів із кінця даного типу даних.

```javascript
[1, 2, 3, 4, 5].at(3) // returns 4

[1, 2, 3, 4, 5].at(-2) // returns 4
```

Типи даних, що підтримують цю функцію:

- Рядок;
- Масив;
- Усі класи Typed Array: Uint8Array тощо.

## 2. Індекси відповідності RegExp

Додавання прапора `/d` до регулярного виразу створює відповідні об’єкти, які записують початок і кінець кожного захоплення групи.

Існують різні способи зіставлення індексів.

- Індекси відповідності для нумерованої групи

```javascript
const matchObj = /(a+)(b+)/d.exec('aaaabb');

console.log(matchObj);
/*
Output -
['aaaabb', 'aaaa', 'bb', index: 0, input: 'aaaabb', groups: undefined, indices: Array(3)]
*/
```

Завдяки прапору регулярного виразу `/d` matchObj також має властивість .indices, яка записує для кожної нумерованої групи, де вона була записана у вхідному рядку.

```javascript
matchObj.indices[1];
// Output - [0, 4]
```

- Індекси відповідності для названих груп

```javascript
const matchObj = /(?<as>a+)(?<bs>b+)/d.exec('aaaabb');

console.log(matchObj);
/*
Output -
['aaaabb', 'aaaa', 'bb', index: 0, input: 'aaaabb', groups: {as: 'aaaa', bs: 'bb'}, indices: Array(3)]
*/
```

Їх індекси зберігаються в `matchObj.indices.groups`.

```javascript
matchObj.indices.groups;
// Output - { as: [0,4], bs: [4,6] }
```

## 3.Object.hasOwn(obj, propKey)

Це безпечний спосіб перевірити, чи `propKey` є **власністю** об’єкта `obj`. Він схожий на `Object.prototype.hasOwnProperty`, але підтримує всі типи об’єктів.

```javascript
const proto = {
  protoProp: 'protoProp',
};

const obj = {
  __proto__: proto,
  objProp: 'objProp',
};

console.log('protoProp' in obj); // output - true
console.log(Object.hasOwn(obj, 'protoProp')) // output - false
console.log(Object.hasOwn(proto, 'protoProp')); // output - true
```

4. `error.cause`

Помилка та її підкласи тепер дозволяють визначити причину помилки. Це корисно в глибоко вкладених функціях, де ми зв’язали блоки помилок, щоб швидко знайти помилку. [Читайте тут для отримання додаткової інформації](https://2ality.com/2021/06/error-cause.html).

```javascript
function readFiles(filePaths) {
  return filePaths.map(
    (filePath) => {
      try {
        // ···
      } catch (error) {
        throw new Error(
          `While processing ${filePath}`,
          {cause: error}
        );
      }
    });
}
```

## 5. Модулі очікування верхнього рівня

Тепер ми можемо використовувати `await` на верхніх рівнях модулів і більше не потрібно вводити асинхронні функції чи методи.

- Динамічне завантаження модулів

```javascript
const messages = await import(`./messages-${language}.mjs`);
```

- Використання резервного варіанту, якщо не вдається завантажити модуль

```javascript
let lodash;

try {
  lodash = await import('https://primary.example.com/lodash');
} catch {
  lodash = await import('https://secondary.example.com/lodash');
}
```

- Використання будь-якого ресурсу, який завантажується найшвидше

```javascript
const resource = await Promise.any([
  fetch('http://example.com/first.txt')
    .then(response => response.text()),
  fetch('http://example.com/second.txt')
    .then(response => response.text()),
]);
```

## 6. Нові учасники класів

- Публічні властивості можна створити за допомогою публічні поля екземпляра

```js
class InstPublicClass {
  // Instance public field
  instancePublicField = 0; // (A)

  constructor(value) {
    // We don’t need to mention .property elsewhere!
    this.property = value; // (B)
  }
}

const inst = new InstPublicClass('constrArg');
```

- Статичні публічні поля

```js
const computedFieldKey = Symbol('computedFieldKey');

class StaticPublicFieldClass {
  static identifierFieldKey = 1;
  static 'quoted field key' = 2;
  static [computedFieldKey] = 3;
}

console.log(StaticPublicFieldClass.identifierFieldKey) //output -> 1
console.log(StaticPublicFieldClass['quoted field key']) //output -> 2
console.log(StaticPublicFieldClass[computedFieldKey]) //output -> 3
```

- Приватні слоти є новими, і їх можна створити через приватні поля екземпляра

```js
class InstPrivateClass {
  #privateField1 = 'private field 1'; // (A)
  #privateField2; // (B) required!

  constructor(value) {
    this.#privateField2 = value; // (C)
  }

  /**
   * Private fields are not accessible outside the class body.
   */
  checkPrivateValues() {
    console.log(this.#privateField1); // output -> 'private field 1'
    console.log(this.#privateField2); // output -> 'constructor argument'
  }
}

const inst = new InstPrivateClass('constructor argument');
inst.checkPrivateValues();


console.log("inst", Object.keys(inst).length === 0) // output -> inst, true
```

- Екземпляр і статичні приватні поля

```js
class InstPrivateClass {
  #privateField1 = 'private field 1'; // (A)
  #privateField2; // (B) required!

  static #staticPrivateField = 'hello';

  constructor(value) {
    this.#privateField2 = value; // (C)
  }

  /**
   * Private fields are not accessible outside the class body.
   */
  checkPrivateValues() {
    console.log(this.#privateField1); // output -> 'private field 1'
    console.log(this.#privateField2); // output -> 'constructor argument'
  }

  static #twice() {
    return this.#staticPrivateField + " " + this.#staticPrivateField;
  }

  static getResultTwice() {
    return this.#twice()
  }
}

const inst = new InstPrivateClass('constructor argument');
inst.checkPrivateValues();


console.log("inst", Object.keys(inst).length === 0) // output -> "inst", true
console.log(InstPrivateClass.getResultTwice()); // output -> "hello hello"
```

- Приватні методи та засоби доступу

```js
class MyClass {
  #privateMethod() {}

  static check() {
    const inst = new MyClass();

    console.log(#privateMethod in inst) // output-> true
    console.log(#privateMethod in MyClass.prototype) // output-> false
    console.log(#privateMethod in MyClass) // output-> false
  }
}

MyClass.check();
```

- Статичні блоки ініціалізації в класах. Для статичних даних у нас є **статичні поля** та **статичні блоки**, які виконуються **під час створення класу**

```js
class Translator {
  static translations = {
    yes: 'ja',
    no: 'nein',
    maybe: 'vielleicht',
  };
  static englishWords = [];
  static germanWords = [];
  static { // (A)
    for (const [english, german] of Object.entries(this.translations)) {
      this.englishWords.push(english);
      this.germanWords.push(german);
    }
  }
}

console.log(Translator.englishWords, Translator.germanWords)
// Output -> ["yes", "no", "maybe"], ["ja", "nein", "vielleicht"]
```

- **Перевірки приватних слотів**. Ця функція допомагає нам перевірити, чи об’єкт має вказаний приватний слот

```js
class C1 {
  #priv() {}

  static check(obj) {
    return #priv in obj;
  }
}

console.log(C1.check(new C1())) // output true
```

Ці функції допоможуть нам покращити наші проекти та вдосконалити методи кодування 👩🏻‍💻.