DEV Community

Cover image for What's new in ES2022? 🤔
Jasmin Virdi
Jasmin Virdi

Posted on • Edited on

What's new in ES2022? 🤔

Soon the new version of ECMA Script will become standard in few months. So let's take a glimpse at the features that will be part of ES2022.

Features of ES2022

1. Method .at() of indexable values.

This function let's us reads an element at the given index. It can accept negative indexes to read elements from the end of the given datatype.

For example

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

[1,2,3,4,5].at(-2)   // returns 4
Enter fullscreen mode Exit fullscreen mode

Datatypes supporting this function.

  • String
  • Array
  • All Typed Array classes: Uint8Array etc.

2. RegExp match indices

Adding a flag /d to a regular expression produces match objects that records the start and end of each group capture.

There are different ways to match indices

  • Match indices for numbered group
const matchObj = /(a+)(b+)/d.exec('aaaabb');

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

Due to the regular expression flag /d, matchObj also has a property .indices that records for each numbered group where it was captured in the input string.

matchObj.indices[1];
/*
Output - 
[0, 4]
*/
Enter fullscreen mode Exit fullscreen mode
  • Match indices for named groups
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)]
*/
Enter fullscreen mode Exit fullscreen mode

Their indices are stored in matchObj.indices.groups

matchObj.indices.groups;
/*
Output -
{ as: [0,4], bs: [4,6] }
*/
Enter fullscreen mode Exit fullscreen mode

3. Object.hasOwn(obj, propKey)

It is a safe way to check that propKey is the own property of obj object. It is similar to Object.prototype.hasOwnProperty but it supports all object types.

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.
Enter fullscreen mode Exit fullscreen mode

4. error.cause

Error and it's subclasses now let us specify the reason behind the error. This is useful in deeply nested function where we have chained error blocks to quickly find the error. Read here for more info

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

5. Top-level await modules

We can now use await at the top levels of modules and don’t have to enter async functions or methods anymore.

  • Loading modules dynamically
const messages = await import(`./messages-${language}.mjs`);
Enter fullscreen mode Exit fullscreen mode
  • Using a fallback if module loading fails
let lodash;
try {
  lodash = await import('https://primary.example.com/lodash');
} catch {
  lodash = await import('https://secondary.example.com/lodash');
}
Enter fullscreen mode Exit fullscreen mode
  • Using whichever resource loads fastest
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()),
]);
Enter fullscreen mode Exit fullscreen mode

6. New members of classes

  • Public properties can be created via
    • Instance public fields
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');
Enter fullscreen mode Exit fullscreen mode
  • Static public fields
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
Enter fullscreen mode Exit fullscreen mode
  • Private slots are new and can be created via
    • Instance private fields
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
Enter fullscreen mode Exit fullscreen mode
  • Instance and static private fields
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"
Enter fullscreen mode Exit fullscreen mode
  • Private methods and accessors
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();
Enter fullscreen mode Exit fullscreen mode
  • Static initialisation blocks in classes. For static data we have Static fields and Static Blocks that are executed when the class is created.
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"]
Enter fullscreen mode Exit fullscreen mode
  • Private slot checks - This functionality helps us to check that the object has the given private slot in it.
class C1 {
  #priv() {}
  static check(obj) {
    return #priv in obj;
  }
}

console.log(C1.check(new C1())) // output true
Enter fullscreen mode Exit fullscreen mode

These amazing features will help us to enhance our projects and improve our coding techniques. I am really excited to try these features out in my project. 💃

Happy Coding! 👩🏻‍💻

Latest comments (75)

Collapse
 
shaun0703 profile image
Shaun47

Hi jess hun how are you?

Collapse
 
zyabxwcd profile image
Akash

Short and crisp. Thumbs up for that but one minor feedback though, it would have been great if practical/possible use cases around it would have been shown or told on top of the syntax. Cheers!

Collapse
 
jasmin profile image
Jasmin Virdi • Edited

Thanks for sharing the feedback. Will definitely work on it. 🙌

Collapse
 
blackjyn profile image
ZVHR El Ekhsaan

All we need is actually implementation of ES4. That way, not only it solves many problems, we also dont need TypeScript__

Collapse
 
blackjyn profile image
ZVHR El Ekhsaan

All we need is actually implementation of ES4. That way, not only it solves many problems, we also dont need TypeScript

Collapse
 
code_rabbi profile image
Emeka Orji

In all these, I guess I will be using Array.at(index) more.

Collapse
 
oanouman profile image
Martial Anouman

Great summary. Thanks

Collapse
 
mikmik1011 profile image
Misa Stefanovic

bruh, isn't .at(3) literally the same thing as [3]

i swear to god js is just becoming the huge pile of this random stupid functions

Collapse
 
zhengzheren profile image
zhengzheren

hi there?

Collapse
 
serenawilliams profile image
SerenaWilliams

how to access a private field from outside of the class ? wazifa to marry someone you love

Collapse
 
romulocintra profile image
romulocintra:dev

That's a nice summary please looking forward to see you around TC39 Educators call @jasmin github.com/tc39/js-outreach-groups

Collapse
 
jasmin profile image
Jasmin Virdi

Hey,

Thank you soo much. Can you please share more details about this?😅

Collapse
 
romulocintra profile image
romulocintra:dev

Hello, you can fill a form there github.com/tc39/js-outreach-groups then I can invite you for our next meeting :)

Thread Thread
 
jasmin profile image
Jasmin Virdi

Thank you so much!
Filled the form!🙂