“This is the first day of my participation in the First Challenge 2022. For details: First Challenge 2022”

Take a look at some of the features and apis that will impact JavaScript developers in the 2021 V8 release, and feel free to try them out in the latest Chrome update.

The findLast and findLastIndex methods of arrays

Unlike the find and findIndex methods on arrays, findLast and findLastIndex find elements backwards.

Arrar.prototype.find returns the first element that matches the condition

Arrar. Prototype. FindIndex return the first qualifying element subscript

Arrar.prototype.findLast returns the first qualifying element from back to back, as opposed to the last qualifying element for find

Arrar. Prototype. FindLastIndex again, return to the last of the elements of an eligible subscript

let arr = [1.2.3.4.5]

arr.find(item= > item%2= = =0) / / 2
arr.findIndex(item= > item%2= = =0) / / 1

arr.findLast(item= > item%2= = =0) / / 4
arr.findLastIndex(item= > item%2= = =0) / / 3
Copy the code

Static code block

The static methods/attributes that define a class are pretty much optional. V8 added support for static code blocks in v9.4. Static code blocks run only once

Its runtime is immediately after the class is parsed.

This is not consistent with Java, but it makes sense for JavaScript, which is an interpreted language and has no classloading mechanism.

Static code blocks generate their own scopes, and this, like this in static methods, refers to the class itself

console.log(1);
class Person {
    static {
        console.log('Nuwa created man.');
        console.log(this === Person); // true
    }

    constructor (name) {
        this.name = name; }}console.log(2);
Copy the code

Object.hasOwn

Object. HasOwn is Object. The prototype. The hasOwnProperty. Call the alias, used to detect whether an Object contains a certain property, its the first parameter is the tested Object, the second parameter is the need to detect the properties.

let obj = { prop: 42 };

obj.hasOwnProperty('prop')// true

Object.prototype.hasOwnProperty.call(obj, 'prop')
Object.hasOwn(obj, 'prop')// true
Copy the code

Chicken ribs and comparing the individual feels this way, the all things all belong to the Object in the js, inevitably there are hasOwnProperty method, what is the scenario would anyone go through Object. The prototype. The hasOwnProperty. Call the way to judge? Doesn’t it smell good to call hasOwnProperty directly

Method the at

The AT method was released in V9.2, and the new AT method works with Arrays, TypedArrays, and Strings. When a negative value is passed, it performs a relative index from the indexable end. When passing a positive value, it behaves the same as property access. For example, [1,2,3].at(-1) is 3

The at method was created to easily access the index of an array. The at method, when passed a negative number, can indicate the number of elements in the penultimate. This frees up the writing of arr[arr.lenght-1]

let arr = [1.2.3.4.5]

arr.at(-1); / / 5
arr.at(0); / / 1
arr.at(4); / / 5
arr.at(5); // undefined
Copy the code

The top await

Top-level await enables developers to use the await keyword in global scope. It’s like a big async function that wraps the global code. It actually came out in 2019, but it wasn’t enabled by default until V8 made it default in V9.1.

before

Before top-level await support, using await in global code causes a SyntaxError

// test.js
await Promise.resolve(console.log('πŸŽ‰'));
// β†’ SyntaxError: await is only valid in async function

(async function() {
  await Promise.resolve(console.log('πŸŽ‰'));
  / / > πŸŽ‰} ());Copy the code

now

The top-level await now supports the use of await in global code

// test.js
await Promise.resolve(console.log('πŸŽ‰'));
/ / > πŸŽ‰

(async function() {
  await Promise.resolve(console.log('πŸŽ‰'));
  / / > πŸŽ‰} ());Copy the code

Note: Top-level await applies only to the top level of the module. Not supported in normal functions

example

I find this useful when you use import() to dynamically import dependencies.

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

Or if your module needs to initialize some asynchronous event before it can be used, it can generate an error if initialization fails.

const connection = await dbConnector();
Copy the code

Example: Try to load A JavaScript library from CDN A and revert to CDN B if that fails:

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

The IN operator supports detecting private attributes

The IN operator can be used to detect whether an object contains an attribute

const o1 = {'foo': 0};
console.log('foo' in o1); // true
const o2 = {};
console.log('foo' in o2); // false
const o3 = Object.create(o1);
console.log('foo' in o3); // true
Copy the code

However, after js supports defining private properties/methods using properties or method names starting with #. The IN operator cannot detect private attributes.

class User {
    #password;// Private attributes must be clearly defined, otherwise they cannot be obtained through this.#password
    constructor (username, password) {
        this.username = username;
        this.#password = password; }}let yuexi = new User('yuexi'.'123');

yuexi.username // yuexi
'username' in yuexi // true

yuexi.password // undefined
yuexi['#password'] // undefined
'#password' in yuexi // false
'password' in yuexi // false
Copy the code

In v9.1, V8 added support for detecting private attributes with the IN operator. But this can still only be used within a class

class User {
    #password;
		
  	static hasPassword(obj){
      return #foo inobj; }}Copy the code

There are a few extra points to note:

In an inheritance of the extends keyword implementation, a subclass instance receives private fields as its properties from its parent, so all of its subclasses can be detected as private properties by the IN operator

class SubA extends User {};
A.hasPassword(new SubA()); // true
Copy the code

However, if inheritance is implemented via stereotype chain/parasitized, the IN operator cannot detect the parent’s private property because the IN operator does not look up its stereotype chain.

const a = new User();
const o = Object.create(a);
A.hasPassword(o); // false, private fields are inherited rather than owned
A.hasPassword(o.__proto__); // true
Copy the code

Regular expression index

Starting with V9.0, developers can choose to get an array of the start and end positions of a match group in regular expression matching. When a regular expression has the/D flag, the Indices property of its match result stores this array.

const re = /(a)(b)/d;      // Note the /d flag.
const m = re.exec('ab');
console.log(m.indices[0]); // Index 0 is the entire matched subscript
/ / to [0, 2)
console.log(m.indices[1]); // Index 1 is the subscript information for the first group
/ / to [0, 1]
console.log(m.indices[2]); // Index 2 is the subscript of the second group
/ / - [1, 2]
Copy the code