内容简介:JavaScript is one of the most popular programming languages, and features are now added to the language every year. This article covers new features added in ECMAScript 2020, also known as ES11.Before the introduction of ECMAScript 2015, also known as ES6,
JavaScript is one of the most popular programming languages, and features are now added to the language every year. This article covers new features added in ECMAScript 2020, also known as ES11.
Before the introduction of ECMAScript 2015, also known as ES6, JavaScript language development had a very slow pace. Fortunately, since then, new features are added every year. Be aware that not all features might be supported in all modern browsers yet, but thanks to transpilers like Babel , we can use them already today. This article will cover some of the latest additions to JavaScript — ECMAScript 2020 (ES11).
Optional Chaining
I’m sure that most developers are familiar with an error of this kind:
TypeError: Cannot read property ‘x’ of undefined
This error basically means that we tried to access a property on something that is not an object.
Accessing an Object Property
const flower = { colors: { red: true } } console.log(flower.colors.red) // this will work console.log(flower.species.lily) // TypeError: Cannot read property 'lily' of undefined
JavaScript engine will always throw an error in a scenario like this. However, there are cases in which it doesn't matter that the value isn't there yet, because we might know it will be. Fortunately, here is the optional chaining feature to the rescue!
We can use the optional chaining operator, which consists of a question mark and a dot:
?.
, to indicate that an error should not be thrown. Instead, if there is no value, undefined
will be returned.
console.log(flower.species?.lily) // undefined
Optional chaining can also be used when accessing array values or calling a function.
Accessing an 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 a 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
Until recently, whenever there was a need to provide a fallback value, the logical operator
||
had to be used. It works in most cases, but it can't be applied in some scenarios. For instance, if the initial value is a Boolean or a number. Let's take a look at an example below, where we want to assign a number to a variable, or default it to 7 if the initial value is not a number:
let number = 1 let myNumber = number || 7
The myNumber variable is equal to 1, because the left-hand value ( number ) is a truthy value, as 1 is a positive number. However, what if the number variable is not 1, but 0?
let number = 0 let myNumber = number || 7
0 is a
falsy
value, and even though it is a number, the myNumber
variable will have the right-hand value assigned to it. Therefore, myNumber
is now equal to 7. However, that's not really what we want. Fortunately, instead of writing additional code and checks to confirm if the number
variable is indeed a number, we can use the nullish coalescing operator. It consists of two question marks:
??
.
let number = 0 let myNumber = number ?? 7
The right-hand side value will only be assigned if the left-hand value is equal to null or undefined . Therefore, in the example above, the myNumber variable is equal to 0.
Private Fields
Many programming languages that have classes
allow defining class properties as public, protected, or private. Public
properties can be accessed from outside of a class and by its subclasses, while protected
classes can only be accessed by subclasses. However, private
properties can only be accessed from inside of a class. JavaScript supports class syntax since ES6
, but only now were private fields introduced. To define a private property, it has to be prefixed with the 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) // Private name #leaf_color is not defined
If we try to access a private property from outside, an error will be thrown.
Static Fields
To use a class method, a class had to be instantiated first, 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
Trying to access a method without instantiating the Flower class would result in an error. Thanks to static fields, a class method can now be declared with the static keyword and called from outside of a class.
class Flower { constructor(type) { this.type = type; } static create_flower(type) { return new Flower(type); } } const rose = Flower.create_flower("rose"); // Works fine
Top Level Await
So far, to await for a promise to finish, a function in which await is used would need to be defined with the async keyword.
const func = async () => { const response = await fetch(url) }
Unfortunately, if there was a need to await for something in a global scope, it would not be possible, and usually required an immediately invoked function expression (IIFE) .
(async () => { const response = await fetch(url) })()
Thanks to Top Level Await , there is no need for wrapping code in an async function anymore, and this code will work.
const response = await fetch(url)
This feature could be useful for resolving module dependencies or using a fallback source if the initial one failed.
let Vue try { Vue = await import('url_1_to_vue') } catch { Vue = await import('url_2_to_vue) }
Promise.allSettled
To wait for multiple promises to finish, Promise.all([promise_1, promise_2]) can be used. The problem is that if one of them fails, then an error will be thrown. Nevertheless, there are cases in which it is ok for one of the promises to fail, and the rest should still resolve. To achieve that, ES11 introduced Promise.allSettled .
promise_1 = Promise.resolve('hello') primise_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 resolved promise will return an object with status and value properties, while rejected ones will have status and reason .
Dynamic Import
You might have used dynamic imports when using webpack for module bundling. Finally, native support for this feature is here.
// Alert.js file export default { show() { // Your alert } } // Some other file import('/components/Alert.js') .then(Alert => { Alert.show() })
Considering the fact that a lot applications use module bundlers like webpack for transpiling and optimizing code, this feature isn't such a big deal right now.
MatchAll
MatchAll is useful for applying the same regular expression to a string if you need to find all matches and get their positions. The match method only returns items that were matched.
const regex = /\b(apple)+\b/; const fruits = "pear, apple, banana, apple, orange, apple"; for (const match of fruits.match(regex)) { console.log(match); } // Output // // 'apple' // 'apple'
matchAll in contrast, returns a bit more information, including index of the string found.
for (const match of fruits.matchAll(regex)) { console.log(match); } // Output // // [ // '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 can run in different environments like browsers or Node.js. A global object in browsers is available under window variable, but in Node it is an object called global . To make it easier to use a global object no matter in which environment code is running, globalThis was introduced.
// In a browser window == globalThis // true // In node.js global == globalThis // true
BigInt
The maximum number that can be reliably represented in JavaScript is 2^53 - 1. BigInt will allow creation of numbers even bigger than that.
const theBiggerNumber = 9007199254740991n const evenBiggerNumber = BigInt(9007199254740991)
Conclusion
I hope you found this article useful and are as excited as I am about the new features that are coming to JavaScript. If you would like to know more about different features you can check the official GitHub repository of the ES committee here .
以上所述就是小编给大家介绍的《The Latest Features Added to JavaScript in ECMAScript 2020》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。