Need a Website or app? Hire an experienced team of Web and Mobile developers with us.
Free Consultation

New JavaScript Features | ES13 Features | ECMAScript 2022 Features

Learn about these new JavaScript features coming in ES13 or ECMAScript 2022.

Posted by Abdul Rahman on 03 Jun 2022
New JavaScript Features | ES13 Features | ECMAScript 2022 Features

JavaScript is one of the most popular programming languages. One of the reasons for its popularity is its evolution over time. JS is getting better with time and new features are getting to it added regularly. A new specification version of the programming language is being released every year since 2015. This year, the 13th edition of the JavaScript standard, ECMAScript 2022 will be released. ****Some new features and improvements are getting added to the JavaScript with the release of the ES2022. So here, we'll look at some of the new features and will try to understand them with examples.

1. Top-level await

Asynchronous functions were added to JavaScript in 2017. Until now, we could only use await inside the async functions. But now, the await keyword can also be used outside the async functions at the top level of a module to wait for a Promise.

So, while using top-level await in a module where one module imports another one, the execution of the parent module will only start when the execution of the child module code is finished.

Let's have a look at the example to have a better understanding of the feature.

Before ES2022

await Promise.resolve(console.log("Inkoop"))
// SyntaxError: await is only valid in async function

const print = async () => {
  await Promise.resolve(console.log("Inkoop"))
}

print() // Output: Inkoop

After ES2022

await Promise.resolve(console.log("Inkoop")) // Inkoop

2. Private Class Fields and Methods

By default, class fields and methods are public in JavaScript, which means these fields and methods are accessible globally and can be read or modified from outside of the class. Earlier, developers used to prefix class fields with an underscore _ to mark them private. These fields were hidden by convention only. There's nothing which prevents accessing those fields. The JavaScript specification does not give any particular meaning to the fields prefixed with an underscore either.

But now, making class fields or methods private is as simple as prefixing them with a hash #. Unlike the underscore convention, fields and methods which start with # are made private by the JavaScript specification itself. These private fields and methods are only accessible inside the class in which they are declared. Trying to access these fields from outside of the class will throw an error.

class MyClass {
  #firstName = "Lorem"
  lastName = "Ipsum"

  printPrivateField() {
    console.log(this.#firstName)
  }

  #sayBye() {
    console.log("Bye")
  }
}

const instance = new MyClass()
console.log(instance.#firstName) // SyntaxError: Private field '#firstName' must be declared in an enclosing class
console.log(instance.lastName) // Ipsum
instance.printPrivateField() // Lorem
instance.#sayBye() // SyntaxError: Private field '#sayBye' must be declared in an enclosing class

3. at() method for Strings, Arrays, and TypedArrays

So far, we've been using square brackets [] to access the elements of an array. In bracket notation syntax, we just need to pass the index of the element which we want to access inside the square brackets and it returns the item at that particular index. But, to access the elements of an array backwards, we need to use the length property of the array.

Up to this point, we couldn't use negative indexing to get the elements of an array backwards like other languages as JavaScript didn't allow negative indexing. Unfortunately, JavaScript's language design makes it impossible to use negative indexing with bracket notation as bracket notation syntax isn't specific to arrays and strings only, it also applies to objects.

So, ES2022 introduces a new method to Array, String, and TypedArray. The at method is almost similar to the bracket notation as it also takes an integer and returns the item at that index. But, it also supports negative indexing. So now, we can access the elements of an array or a string backwards using the at method with negative indexing.

const array = ["inkoop", "draxlr", "sup"]

// Using the length property
const lastItem = array[array.length - 1]
console.log(lastItem) // Output: sup

// Using the new at method
const lastElement = array.at(-1)
console.log(lastElement) // Output: sup
console.log(array.at(-2)) // Output: draxlr
console.log(array.at(0)) // Output: inkoop

4. Object.hasOwn Method

To check if a property exists in an object or not, now we can use Object.hasOwn method which is a convenient alternative to Object.prototype.hasOwnProperty method. Both of these methods return a boolean which indicates whether the object has the specified property as its own property or not. Object.prototype.hasOwnProperty has been there in JavaScript specification for quite a time now but it had some drawbacks. hasOwnProperty isn't a reserved JavaScript object method and can be overridden. It has one more issue if an object is created using Object.create(null), it does not inherit from Object.prototype which makes the hasOwnProperty unreachable for the created object. Using hasOwnProperty on the object will throw an error.

To overcome these issues, the Object.hasOwn method has been introduced in ES2022. It takes The JavaScript object instance as the first parameter and the name of the property as its second parameter. The method returns true if the specified property exists in the specified object itself, otherwise, it'll return false.

So now, it's better to use Object.hasOwn method instead of the Object.prototype.hasOwnProperty method if the environment supports the newer one.

const object = {
  name: "Draxlr",
}

console.log(object.hasOwnProperty("name")) // Output: true
console.log(object.hasOwnProperty("hasOwnProperty")) // Output: false

// issue with hasOwnProperty
const object2 = Object.create(null)
object2.name = "lorem"
console.log(object2.hasOwnProperty("name")) // TypeError: object2.hasOwnProperty is not a function

// using Object.hasOwn method
console.log(Object.hasOwn(object2, "name")) // Output: true

// another issue
const object3 = {
  name: "JavaScript",
  hasOwnProperty() {
    return false
  },
}
console.log(object3.hasOwnProperty("name")) // Output: false

// using Object.hasOwn method
console.log(Object.hasOwn(object3, "name")) // Output: true
console.log(Object.hasOwn(object3, "hasOwnProperty")) // Output: true

5. RegExp match indices

ES2022 adds a new feature to Regular Expressions called Match indices. With the help of this feature, we can get extra information about the start and end indices of the captured substring. To get this additional information, we just need to pass the/d flag in the regular expression. This feature adds indices property to the result array returned by RegExp.prototype.exec and String.prototype.matchAll methods. The indices property is an array which contains the start and end indices of each matched substring relative to the starting of the input.

Let's understand it better with an example.

const str = "next time there won't be a next time."

// without /d flag
const regex = /(next)/g
console.log(...str.matchAll(regex))

// Output:
// [
//   'next',
//   'next',
//   index: 0,
//   input: "next time there won't be a next time.",
//   groups: undefined
// ] [
//   'next',
//   'next',
//   index: 27,
//   input: "next time there won't be a next time.",
//   groups: undefined
// ]

// with /d flag
const regex2 = /(next)/dg
console.log(...str.matchAll(regex2))
// Output:
// [
//   'next',
//   'next',
//   index: 0,
//   input: "next time there won't be a next time.",
//   groups: undefined,
//   indices: [ [ 0, 4 ], [ 0, 4 ], groups: undefined ]
// ] [
//   'next',
//   'next',
//   index: 27,
//   input: "next time there won't be a next time.",
//   groups: undefined,
//   indices: [ [ 27, 31 ], [ 27, 31 ], groups: undefined ]
// ]

6. Ergonomic brand checks for Private Fields

As mentioned earlier in the blog, ES13 adds private class fields feature to JavaScript but what if we want to check if a private field exists in the class or not. Private fields have a built-in brand check, so accessing a non-existent private field on a class throws an exception. Meanwhile, trying to access a non-existent public field returns undefined.

Using try/catch to handle the exception will work in some cases, but won't that be awkward. Don’t worry as ES13 also comes up with a better syntax to check for a private field in a class. We can simply use the in operator to check whether a private field or method exists in a class or not. The in operator returns true if the specified private field or method has been declared, otherwise false.

class User {
  #name = "Random User"

  static isNamePresent(object) {
    console.log(#name in object)
  }
}
const instance = new User()

User.isNamePresent(instance) // Output: true
User.isNamePresent({}) // Output: false

Hope you found this blog helpful and got to learn something new. All of the above-listed features are now available in most of the browsers. So, you can also go and check out these features.


Need a Website or app? Hire an experienced team of Web and Mobile developers with us.
Free Consultation

Related Services.



Hire ReactJS Developers
Hire Gatsby Developers
Hire NextJS Developers

We support the Open Source community.



Have a Project in mind?