JavaScript is one of the most dynamic languages. Each year, multiple features are added to make the language more manageable and practical.
Like a lot of other programming languages, JavaScript is constantly evolving. Every year, the language is made more powerful with new capabilities that let developers write more expressive and concise code.
Let’s explore the most recent features added in ECMAScript 2022 (ES13), and see examples of their usage to understand them better.
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.
Before ES2022
await Promise.resolve(console.log('Hello Javascript'));
// Output: SyntaxError: await is only valid in async function
// Alternative to fix the problem
(async function() {
await Promise.resolve(console.log('Hello Javascript'));
// Output: Hello World
}());
After ES2022
await Promise.resolve(console.log('Hello Javascript'));
//Hello Javascript
2. Class field declarations
Before ES13, class fields could only be declared in their constructor. But now we can declare or define them in the outermost scope of the class.
Before ES2022
class team{
constructor() {
this.teamName = 'Avengers';
this.teamMember = 10;
}
}
const oppositeTeam = new team();
console.log(oppositeTeam.teamName); // Avengers
After ES2022
class team {
teamName = 'Avengers';
teamMember = 10;
}
const oppositeTeam = new team();
console.log(oppositeTeam.teamName); // Avengers
3. Private instance fields, methods, and accessors
Previously when was needed to declare a private method or field needs to be added an underscore _ at the beginning of the method name (based on convention), however, that does not guarantee that the method will be private.
With ES2022 was added as new features such as private instance fields, methods, and accessors. We need to add just # at the beginning of the method name and in that way will be declared private.
Before ES2022
class Person {
_firstName = 'Merry';
lastName = 'Smith';
printPrivateField() {
console.log(this.#firstName) // Merry
}
#sayHello() {
console.log("Hello")
}
}
const user = new Person();
// Members intended to be private can still be accessed from outside the class
console.log(person._firstName); // Merry
person._firstName = 'Robert'; // They can also be modified
After ES2022
class Person {
#firstName = "Merry"
lastName = "Smith"
printPrivateField() {
console.log(this.#firstName) // Merry
}
#sayHello() {
console.log("Hello")
}
}
const user = new Person()
console.log(user.#firstName) // SyntaxError: Private field '#firstName' must be declared in an enclosing class
console.log(user.lastName) // Smith
user.printPrivateField() // Merry
user.#sayHello() // SyntaxError: Private field '#sayHello' must be declared in an enclosing class
4. Ergonomic brand checks for Private Fields
This functionality helps us to check that the object has the given private slot in it, for this purpose, the in operator is used.
class Person {
#name = "Random User"
isNamePresent () {
return #name in this;
}
}
const user = new Person()
console.log(user.isNamePresent());//true
5. Static Class Fields and Static Private Methods
We can now declare static fields and static private methods for a class in ES13. Static methods can access other private/public static members in the class using the this keyword, and instance methods can access them using this.constructor.
class Person {
static #marks = 25;
static getMarks() {
return this.#marks;
}
constructor() {
this.constructor.#incrementMarks();
}
static #incrementMarks() {
this.#marks++;
}
}
const user= new Person();
console.log(Person.getMarks()); // 2
6.at() method for Strings, Arrays, and TypedArrays
Until this point, programmers have asked for the ability to do negative indexing of JS Arrays, as you can do with other programming languages. That is, asking for the ability to write arr[-1] instead of arr[arr.length-1], where negative numbers count backward from the last element.
This year with ES2022 we have a big change with a new method that helps programmers with the negative indexing, the .at() method that is supported by Array, String, or TypedArray.
Before ES2022
const array = ["a", "b", "c"]
// Using the length property
const lastItem = array[array.length - 1]
console.log(lastItem) // Output: "c"
After ES2022
const array = ["a", "b", "c"]
// Using the new at method
const lastElement = array.at(-1)
console.log(lastElement) // Output: "c"
7. RegExp Match Indices
ES2022 adds a new feature to Regular Expressions called Match indices. using this we can get extra information about the start and end indices of the captured substring. To use this feature 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 that contains the start and end indices of each matched substring relative to the starting of the input.
Before ES2022
const str = "welcome to welcome"
// without /d flag
const regex = /(welcome)/g
console.log(...str.matchAll(regex));
//output
[
'welcome',
'welcome',
index: 0,
input: 'welcome to welcome',
groups: undefined
]
After ES2022
const str = "welcome to welcome"
// without /d flag
const regex = /(welcome)/dg
console.log(...str.matchAll(regex));
//output
[
'welcome',
'welcome',
index: 0,
input: 'welcome to welcome',
groups: undefined,
indices: [ [ 0, 7 ], [ 0, 7 ], groups: undefined ]
]
8. Object.hasOwn()
In JavaScript we already have an Object.prototype.hasOwnProperty but it’s best to not use hasOwnProperty outside the prototype itself as it is not a protected property, meaning that an object could have its property called hasOwnProperty
Before ES2022
const object = {
name: "Draxlr",
hasOwnProperty (){
return false
}
}
console.log(object.hasOwnProperty("name")); // false
console.log(object.hasOwnProperty("hasOwnProperty")); // false
After ES2022
const user = {
name: "JavaScript",
hasOwnProperty() {
return false;
},
}
console.log(Object.hasOwn(user, "name")); // Output: true
console.log(Object.hasOwn(user, "hasOwnProperty")); // Output: true
9. Error Cause
Error and its subclasses now let us specify the reason behind the error. Sometimes, we catch errors that are thrown during more deeply nested function calls and would like to attach more information to them.
With the Error cause, we can add more intrinsic information for our errors. To use this new feature, we should specify the error options as a second parameter, and with the cause key we can pass the error that we want to chain.
const getUsers = async(array)=> {
try {
const users = await fetch('https://myapi/myusersfake');
return users;
}
catch (error) {
console.log('enter');
throw new Error('Something when wrong, please try again later',
{cause: error });
}
}
try{
const users = getUsers();
}
catch(error) {
console.log(error);
// Error: The array need a minimum of two elements
console.log(error.cause); // TypeError: Failed to fetch
}
10. Array Find from Last
In JavaScript we already have an Array.prototype.find and Array.prototype.findIndex. We know how to find from last may have better performance (The target element on the tail of the array, could append with push or concat in a queue or stack, eg: recently matched time point in a timeline). If we care about the order of the elements (May have a duplicate item in the array, eg: last odd in the list of numbers), a better way to use new methods Array.prototype.findLast and Array.prototype.findLastIndex.
Before ES2022
const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
const isLargeNumber = (element) => element > 10;
console.log(found);//12
console.log(array1.findIndex(isLargeNumber));//1
After ES2022
const array1 = [5, 12, 8, 130, 44];
const found = array1.findLast(element => element > 10);
const isLargeNumber = (element) => element > 10;
console.log(found);//44
console.log(array1.findLastIndex(isLargeNumber));//4
Conclusion
So we have learned the latest features ES2022 brings to JavaScript. Use them to improve your code efficiency and boost your productivity as a developer and write cleaner code with greater conciseness and clarity.