Home  >  Article  >  WeChat Applet  >  What's new in ECMAScript 2020

What's new in ECMAScript 2020

hzc
hzcforward
2020-06-12 10:57:153797browse

Whats new in ECMAScript 2020

JavaScript is one of the most popular programming languages, with new features added every year. This article introduces the new features added in ECMAScript 2020 (also known as ES11).

Before the introduction of ECMAScript 2015 (also known as ES6), JavaScript was developing very slowly. But since 2015, new features have been added every year. It should be noted that not all features are supported by modern browsers, but thanks to the JavaScript compiler Babel, we can already use the new features. This article will introduce some of the latest features of ECMAScript 2020 (ES11).

Optional Chaining Optional chaining call


Most developers have encountered this problem:

TypeError: Cannot read property 'x' of undefined

This error means that we are accessing a property that does not belong to the object.

Accessing the properties of an object

const flower = {
    colors: {
        red: true
    }
}
console.log(flower.colors.red) // 正常运行

console.log(flower.species.lily) // 抛出错误:TypeError: Cannot read property 'lily' of undefined

In this case, the JavaScript engine will throw an error like this. But in some cases it doesn't matter whether the value exists because we know it will. So, optional chained calls come in handy!

We can use the optional chain operator consisting of a question mark and a dot to indicate that an error should not be raised. If there is no value, undefined should be returned.

console.log(flower.species?.lily) // 输出 undefined

Optional chained calls can also be used when accessing an array or calling a function.

Accessing the array

let flowers =  ['lily', 'daisy', 'rose']

console.log(flowers[1]) // 输出:daisy

flowers = null

console.log(flowers[1]) // 抛出错误:TypeError: Cannot read property '1' of null
console.log(flowers?.[1]) // 输出:undefined

Calling the function

let plantFlowers = () => {
  return 'orchids'
}

console.log(plantFlowers()) // 输出:orchids

plantFlowers = null

console.log(plantFlowers()) // 抛出错误:TypeError: plantFlowers is not a function

console.log(plantFlowers?.()) // 输出:undefined

Nullish Coalescing Null value merging


Currently, to provide a fallback value for a variable, the logical operator || is still required. It is suitable for many situations, but cannot be applied in some special scenarios. For example, the initial value is a Boolean value or a number. For example, we want to assign a number to a variable. When the initial value of the variable is not a number, it defaults to 7:

let number = 1
let myNumber = number || 7

The variable myNumber is equal to 1, because the left (number) is a true value 1 . But what if the variable number is not 1 but 0?

let number = 0
let myNumber = number || 7

0 is a false value, so even though 0 is a number. The variable myNumber will be assigned the value 7 on the right. But the result is not what we want. Fortunately, the union operator consisting of two question marks: ?? can check whether the variable number is a number without writing additional code.

let number = 0
let myNumber = number ?? 7

The value on the right side of the operator is only valid when the value on the left is equal to null or undefined. Therefore, the variable myNumber in the example now has a value equal to 0.

Private Fields Private Fields


Many programming languages ​​with classes allow defining classes as public, protected or private properties. Public properties can be accessed from outside the class or subclasses, protected properties can only be accessed by subclasses, and private properties can only be accessed within the class. JavaScript has supported class syntax since ES6, but private fields were not introduced until now. To define a private property, it must be preceded by a hash symbol: #.

class Flower {
  #leaf_color = "green";
  constructor(name) {
    this.name = name;
  }

  get_color() {
    return this.#leaf_color;
  }
}

const orchid = new Flower("orchid");

console.log(orchid.get_color()); // 输出:green
console.log(orchid.#leaf_color) // 报错:SyntaxError: Private field '#leaf_color' must be declared in an enclosing class

If we access the private properties of the class from the outside, an error will inevitably be reported.

Static Fields Static Fields


If you want to use class methods, you must first instantiate a class, as shown below:

class Flower {
  add_leaves() {
    console.log("Adding leaves");
  }
}

const rose = new Flower();
rose.add_leaves();

Flower.add_leaves() // 抛出错误:TypeError: Flower.add_leaves is not a function

Attempting to access a method of a Flower class that has not been instantiated will throw an error. But due to static fields, class methods can be declared with the static keyword and then called from outside.

class Flower {
  constructor(type) {
    this.type = type;
  }
  static create_flower(type) {
    return new Flower(type);
  }
}

const rose = Flower.create_flower("rose"); // 正常运行

Top Level Await Top Level Await


Currently, if you use await to get the result of a promise function, the function using await must be defined with the async keyword.

const func = async () => {
    const response = await fetch(url)
}

The headache is that it is basically impossible to wait for certain results in the global scope. Unless using an immediately invoked function expression (IIFE).

(async () => {
    const response = await fetch(url)
})()

But after the introduction of top-level Await, there is no need to wrap the code in an async function, as follows:

const response = await fetch(url)

This feature cannot be used to solve module dependencies or when the initial source This is very useful when a backup source is needed.

let Vue
try {
    Vue = await import('url_1_to_vue')
} catch {
    Vue = await import('url_2_to_vue)
}

Promise.allSettled method

When waiting for multiple promises to return results, we can use Promise.all([promise_1, promise_2]). But the problem is that if one of the requests fails, an error will be thrown. However, sometimes we hope that after a request fails, the results of other requests can be returned normally. For this situation, ES11 introduced Promise.allSettled.

promise_1 = Promise.resolve('hello')
promise_2 = new Promise((resolve, reject) => setTimeout(reject, 200, 'problem'))

Promise.allSettled([promise_1, promise_2])
    .then(([promise_1_result, promise_2_result]) => {
        console.log(promise_1_result) // 输出:{status: 'fulfilled', value: 'hello'}
        console.log(promise_2_result) // 输出:{status: 'rejected', reason: 'problem'}
    })

A successful promise will return an object containing status and value, and a failed promise will return an object containing status and reason.

Dynamic Import Dynamic Import


You may have used dynamic import in webpack's module binding. But native support for this feature has arrived:

// Alert.js
export default {
    show() {
        // 代码
    }
}


// 使用 Alert.js 的文件
import('/components/Alert.js')
    .then(Alert => {
        Alert.show()
    })

考虑到许多应用程序使用诸如 webpack 之类的模块打包器来进行代码的转译和优化,这个特性现在还没什么大作用。

MatchAll 匹配所有项


如果你想要查找字符串中所有正则表达式的匹配项和它们的位置,MatchAll 非常有用。

const regex = /\b(apple)+\b/;
const fruits = "pear, apple, banana, apple, orange, apple";


for (const match of fruits.match(regex)) {
  console.log(match); 
}
// 输出 
// 
// 'apple' 
// 'apple'

相比之下,matchAll 返回更多的信息,包括找到匹配项的索引。

for (const match of fruits.matchAll(regex)) {
  console.log(match);
}

// 输出
// 
// [
//   'apple',
//   'apple',
//   index: 6,
//   input: 'pear, apple, banana, apple, orange, apple',
//   groups: undefined
// ],
// [
//   'apple',
//   'apple',
//   index: 21,
//   input: 'pear, apple, banana, apple, orange, apple',
//   groups: undefined
// ],
// [
//   'apple',
//   'apple',
//   index: 36,
//   input: 'pear, apple, banana, apple, orange, apple',
//   groups: undefined
// ]

globalThis 全局对象


JavaScript 可以在不同环境中运行,比如浏览器或者 Node.js。浏览器中可用的全局对象是变量 window,但在 Node.js 中是一个叫做 global 的对象。为了在不同环境中都使用统一的全局对象,引入了 globalThis 。

// 浏览器
window == globalThis // true

// node.js
global == globalThis // true

BigInt


JavaScript 中能够精确表达的最大数字是 2^53 - 1。而 BigInt 可以用来创建更大的数字

const theBiggerNumber = 9007199254740991n
const evenBiggerNumber = BigInt(9007199254740991)

结论


我希望这篇文章对您有用,并像我一样期待 JavaScript 即将到来的新特性。如果想了解更多,可以看看 tc39 委员会的官方Github仓库

推荐教程:《JS教程

The above is the detailed content of What's new in ECMAScript 2020. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete