The introduction

The new version of ECMA Script will become standard this June. Let’s see what’s new in ES2022.

New features

1. error.cause

This is a feature about error catching, and the code below lists three ways we used to catch errors in the past.

async function doJob() {
  const rawResource = await fetch('/test')
    .catch(err= > {
      // The following three ways are common in the past to catch errors in code
      
      // 1. Throw new Error(' Failed to download resource: '+ err.message);
      
      // 2. Const wrapErr = new Error(' Failed to download resource ');
      // wrapErr.cause = err;
      // throw wrapErr;
      
      // 3. class CustomError extends Error {
      // constructor(msg, cause) {
      // super(msg);
      // this.cause = cause;
      / /}
      / /}
      // throw new CustomError(' Failed to download resource ', err);})}await doJob(); // => Uncaught Error: Failed to fetch

Copy the code

Past ways of capturing errors were complicated, and there was no consensus among developers on which attribute to use to capture the context of the error.

The new feature is to add an additional option parameter, cause, to the Error constructor, whose value is assigned as an attribute to the Error instance. Therefore, errors can be linked together.

async function doJob() {
  const rawResource = await fetch('/test')
    .catch(err= > {
      throw new Error('Downloading resource failed', { cause: err });
    });
}

try {
  await doJob();
} catch (e) {
  console.log(e);
  console.log('Caused by', e.cause);
}
// Error: Failed to download resources
// Caused by TypeError: Failed to fetch
Copy the code
2. Top-level await

We can now use await at the top of the module and no longer need to use it in conjunction with async functions.

Top-level await can have the following uses in actual production.

  • Dynamic loading module
const strings = await import(`/i18n/${navigator.language}`);
Copy the code

This allows a module to use runtime values to determine dependencies. This is useful for development/production split, internationalization, environment split, and so on.

  • Resource initialization
const connection = await dbConnector();
Copy the code

Allow modules to represent resources.

  • Rely on the back
let jQuery;
try {
  jQuery = await import('https://cdn-a.com/jQuery');
} catch {
  jQuery = await import('https://cdn-b.com/jQuery');
}
Copy the code

When a dependency fails, you can roll back to an older version to prevent the program from crashing.

3. Object.hasOwn(obj, propKey)

Object. HasOwn () method is better than the Object. The prototype. The hasOwnProperty () method is more convenient and safe strategy.

For example, object.create (null) creates an Object that does not inherit from Object.prototype, making the hasOwnProperty method inaccessible.

Object.create(null).hasOwnProperty("foo")
// Uncaught TypeError: Object.create(...) .hasOwnProperty is not a function
Copy the code

Object.hasown (obj, propKey) use case.

let object = { foo: false }
Object.hasOwn(object, "foo") // true

let object2 = Object.create({ foo: true })
Object.hasOwn(object2, "foo") // false

let object3 = Object.create(null)
Object.hasOwn(object3, "foo") // false
Copy the code
4. RegExp match indices

Regular expressions, after/I /m /g, add /d to the matching pattern. After using /d, when we use exec() method, the return value will add a new property indices.

A quick review of the exec() method.

Exec () matches strings more richly than the usual search() test(), and returns an array containing the results of matches, or null if no match is found

let regx = /a+(? 
      
       z)? /g
      ; 
let string = "xaaaz"
let result = regx.exec(string);
// ['aaaz', 'z', index: 1, input: 'xaaaz', groups: {Z:'z'}]
Copy the code

(?

) is a regular syntax added to ES 2018 that allows us to name and group portions of regular content. In the above example, /a+(?

z)? /g means that at least one A and 0 or 1 Z are matched, which contains a capture group named Z. When used with exec() method, we can directly obtain the information of the capture group: Result. groups: undefined if the capture group’s regular syntax is not used in the re

Although the exec() return value provides the index attribute to show the index location of the first match and the groups attribute provides information about the capture group, this information may not be sufficient in some more advanced scenarios. For example, an implementation of syntactic highlighting requires not only matched indexes, but also the start and end indexes of a single capture group, i.e., the Z capture group’s index information in the above example.

In the new feature, a new property indices is added to the return value of the exec() method when the /d matching pattern is used.

const re = /a+(? 
      
       z)? /
      d;
const s = "xaaaz";
console.log("Matching result:", re.exec(s));
/ / / 'aaaz' and 'z', the index: 1, the input: 'xaaaz' groups: {z: 'z'}, indices: [[1, 5], [4, 5]]
Copy the code

The indices property contains the information of the capture group, where [1, 5] is the matching information of all strings of AAAZ, and [4, 5] is the matching index information of the capture group Z.

5. New members of classes
  • Simple variable declaration

Class supports declaring variables directly outside of constructor, whereas previously we had to declare them internally.

class Cat {
  gender = 'female'
}
let cat = new Cat()
cat.gender // female
Copy the code
  • Private variables and private methods

Encapsulation is one of the core principles of object-oriented programming. It is usually implemented using visibility modifiers, such as private or public.

A recent change to class added a # to mark a variable, method, or accessor in a class as private.

class Cat {
  #name = 'kitty'
  gender = 'female'

  setName = () = > {
    this.#name = 'jack'
      console.log(this.#name)
  }

  #setGender = () = > {
    this.gender= 'male'}}let cat = new Cat()
cat.#name // SyntaxError
cat.gender // 'female'
cat.setName() // 'jack'
cat.#setGender // SyntaxError
Copy the code
  • Existence check for private fields

Because trying to access a private field that does not exist on an object raises an error and throws a program exception, you need to be able to check that the object has a given private field.

Class introduces the keyword in to solve the problem of directly reporting errors when accessing private variables.

class Example {
  #field

  static isExampleInstance(object) {
    return #field inobject; }}const ex = new Example()
Example.isExampleInstance(ex) // true
Example.isExampleInstance({}) // false
Copy the code

The isExampleInstance method determines whether an object contains #field.

6. The at ()

We’ve talked about this feature in the past. # JS is about to release 4 new features for arrays and learn to brag about them

.at() allows us to read elements at a given index. It can accept negative indexes to read elements from the end of a given data type.

We used to get the end element of the array like this:

const arr = [1.2.3.4.5]; 
arr[arr.length-1] / / 5
Copy the code

Now at() can easily do the task:

const arr = [1.2.3.4.5]; 
arr.at(-1) / / 5
Copy the code

The semantics of the code will be more intuitive and refreshing, very convenient!

Supported types:

  • String
  • Array
  • Typed Array

If it is helpful to you, I hope you can click “like” and pay attention to the collection. Your encouragement is our motivation to continue to promote the new features of Javascrpit language.

Previous selections:

JS is about to release 4 new features for arrays and learn to brag about them

Date, the most troublesome object in JS history, is going to be eliminated. The substitute Temporal is really good


If you want to join 360 Group, please send your resume to [email protected].

Editor: Wang Ming

Review: Li Zhijie