It has been eight years since ECMAScript officially released ES6 in 2015. Since 2015, a new version will be released in June every year, with the year at that time as the version number.
Many new features have appeared in these many versions. In order to facilitate memory, I have organized all new features in this article.
ps: Some information says that all versions after ES2015 are collectively called ES6, and some say that ES6 means ES2015, ES7 means ES2016, and so on, which will not be discussed here.
ES2015 is the version with the biggest changes. Basically all the content before ES2015 has been expanded, as shown in the following figure:
Before ES6, there was only one way to declare variables, which was to use the var
keyword. In ES2015, let
and const
keywords were added to declare variables and constants.
The code is as follows:
// Declaration Variable let v = 100 v = 200 // Declare constant const V = 200 // Modify constants // V = 300 // Report errors.
Variables or constants declared using let
and const
keywords have block-level scope.
The sample code is as follows:
{ var v = 100 } { let val = 200 } console.log(v) console.log(val) // Error val is not defined
It is worth noting that variables declared using let
or const
keywords do not have the characteristics of variable promotion, and there is a temporary dead zone.
allows functions to use default values in ES2015. The sample code is as follows:
// Before es2015 function foo(v) { v = v ? v : 100 return v } //es2015 function bar(v = 100) { return v }
It is worth noting that if there are multiple parameters, the default parameters must be used from back to front .
Arrow functions are added in ES2015, which are a shorthand form of functions . The sample code is as follows:
function foo(v) { return v`` } // Arrow function is written const foo = (v) => { return v } // abbreviation 1 const foo = v => { // Only one parameter can omit the parentheses return v } // abbreviation 2 const foo = v => v // You can omit return and curly braces when there is only return in the statement.
It is worth noting that this
of the arrow function is determined based on the execution context, and this
is not bound internally.
When using arrow functions, there is no internal arguments object, but the remaining parameters are used instead.
The example code is as follows:
const foo = (...args) => { // console.log(arguments) // ReferenceError: arguments is not defined console.log(args) // args is an array} foo(1, 2, 3, 4) // [1, 2, 3, 4]
The name attribute added to the function in ES2015 points to the name of the function.
The sample code is as follows:
function foo(v) { return v } const bar = v => v console.log(foo.name) // foo console.log(bar.name) //Extension of bar
. The expansion of value in ES2015 mainly adds some methods to Math
and Number
objects, as well as binary and octal representation methods.
In ES2015, 0b
or 0B
is used to represent binary, and 0o
or 0O
is used to represent octal.
The sample code is as follows:
console.log(0b111111111 === 511) // true console.log(0o777 === 511) //
The attributes and methods extended by true for Number are as follows:
Attribute/method name | description |
---|---|
Number.EPSILON | Numerical minimum precision |
Number.MIN_SAFE_INTEGER | Minimum safe number ( -2^53 ) |
Number.MAX_SAFE_INTEGER | Maximum safety Number ( 2^53 ) |
Number.parseInt() | parses the parameter into an integer and returns |
Number.parseFloat() | parses the parameter into a floating point number and returns |
Number.isFinite() | to determine whether it is a finite number |
Number.isNaN() | to determine whether it is NaN |
Number.isInteger() | determines whether it is an integer. |
Number.isSafeInteger() | determines whether the value is within the safe range. |
The method for Math extension is as follows:
Method name | description |
---|---|
Math.trunc() | returns the integer part of the value. |
Math.sign() | returns the numerical type (正数1、负数-1、零0 ) |
ES2015 introduces template strings, defined using backtick marks (`). The template string will retain the format, and variables can be used.
The sample code is as follows:
// Use ` to define the template string let str = `a bowl of weeks` // The template string can retain the format let str2 = `A bowl of weeks` // The template string can use the variable const myName = 'A bowl of weeks' let str3 = `author: ${myName}` // Use ${} to wrap
ES2015 also extends some methods for String and String instances, as follows:
Method name | description |
---|---|
String.fromCodePoint() | is used to return the corresponding code point from Unicode String.raw |
() | returns a string with all slashes escaped (that is, a slash is added before the slash), which is often used for template string processing. |
String.prototype.codePointAt() | returns the code point corresponding to the character (the inverse operation of String.fromCodePoint()) |
String.prototype.normalize() | unifies the different representation methods of characters into the same form and returns a new string (Unicode normalization) |
String .prototype.repeat() | repeats the string n times and returns the processed string. |
String.prototype.includes() | determines whether the specified string exists. |
String.prototype.startsWith() | determines whether the string contains the header of the original string. |
String.prototype.endsWith() | determines whether the string exists at the end of the original string. |
the array provides an expansion operator in ES2015, that is..., used in an array to expand the array and separate it with commas,
sample code As follows:
const arr = [1, 2, 3, 4, 5, 6] const newArr = [...arr] // Copy the array console.log(Math.max.call(null, ...arr)) // Use each item in the array as a parameter.
In addition, Array and arrays provide a series of methods, which will be introduced one by one:
Array.from()
: Create an array-like object or iterable object as a new array . The sample code is as follows:
function foo() { return Array.from(arguments) // Convert arguments to array} console.log(foo(1, 2, 3, 4, 5, 6)) // [ 1, 2, 3, 4, 5, 6 ]
Array.of()
: Create a new array with a variable number of arguments Example , the sample code is as follows:
Array.of(1) // [1] Array.of(true, 1, 'A bowl of weeks') // [true, 1, 'A bowl of weeks']
Array.prototype.copyWithin(), shallowly copies part of the array to another location in the same array, and Returning it does not change the length of the original array.
The sample code is as follows:
const arr = [1, 2, 3, 4] // Start at index 2 and copy the content to index 0 at the end arr.copyWithin(0, 2) // [ 3, 4, 3, 4 ]
Array.prototype.find()
, according to the given callback function , find the first matching element, and return undefined if not found . The sample code is as follows:
const arr = [1, 2, 3, 4] arr.find(item => item === 2) // 2 (indicating element),
Array.prototype.findIndex()
, according to the given callback function, find the index of the first matching element, return if not found -1 , the sample code is as follows:
const arr = [1, 2, 3, 4] arr.findIndex(item => item === 2) // 1 (indicates index)
Array.prototype.fill()
, fills the array with the given value . The sample code is as follows:
const arr = [1, 2, 3, 4 ] // Fill index 1-3 with the given value arr.fill('a bowl of weeks', 1, 3) // [ 1, 'a bowl of weeks', 'a bowl of weeks', 4 ]
Array.prototype.keys()
, returns an iterable object whose contents is the key of the array , the sample code is as follows:
const arr = [1, true, 'A bowl of weeks'] const keys = arr.keys() for (const i of keys) { console.log(i) // Traversal results 0 1 2 }
Array.prototype.values()
, returns an iterable object whose content is the value of the array .
The sample code is as follows:
const arr = [1, true, 'A bowl of Zhou'] const values = arr.values() for (const i of values) { console.log(i) // Traversal result 1 true A bowl of weeks}
Array.prototype.entries()
, returns an iterable object whose content is an array. Index 0
is the element of the original array, and 1
is the element of the original array. The value of the position,
the sample code is as follows:
const arr = [1, true, 'A bowl of weeks'] const iterator = arr.entries() console.log(Array.from(iterator)) // [ [ 0, 1 ], [ 1, true ], [ 2, 'A bowl of weeks' ] ]
in ES2015 allows the object's attribute name and attribute value to be consistent You can just write the attribute name.
The sample code is as follows:
const myName = 'A bowl of weeks' const age = 18 const person = { myName, age } console.log(person) // { myName: 'A bowl of Zhou', age: 18 }
In addition, when defining an object, you are allowed to use [] wrapped expressions as attribute names. The sample code is as follows:
const myName = 'A bowl week' const age = 18 const person = { myName, ['a' + 'g' + 'e']: age, } console.log(person) // { myName: 'One Bowl Zhou', age: 18 }
Object.is()
: used to compare whether two values are equal, used to solve NaN ≠= NaN, +0 === - 0 problem,
the sample code is as follows:
console.log(NaN === NaN) // false console.log(+0 === -0) // true console.log(Object.is(NaN, NaN)) // true console.log(Object.is(+0, -0)) // false
Object.assign()
: Copies the values of all enumerable properties from one or more source objects to the target object and returns the target object,
example The code is as follows:
const person = Object.assign({}, { name: 'One Bowl Zhou' }, { age: 18 }) console.log(person) // { name: 'One Bowl Zhou', age: 18 }
Object.getPrototypeOf()
: Get the prototype object ;Object.setPrototypeOf()
: Set the prototype object .put forward the concept of classes in ES2015, and classes are available at the syntax level. The sample code is as follows:
class Person { constructor(age) { //Attribute this.myName = 'A bowl of weeks' this.age = age } // Static method static print() { console.log() } //Accessor get myName() { console.log('getter') return 'a bowl of weeks' } set myName(v) { console.log('setter' + v) } setName(v) { this.myName = v } } const person = new Person(18) person.setName('ywanzhou') // Trigger the setter accessor console.log(person.myName) // Trigger the getter accessor.
proposed the ESModel modularization specification in ES2015, which is the first official level modularization specification. , in this specification we are allowed to use export to export modules and import to introduce modules.
The sample code is as follows:
import a from 'm' // Import the default export in module m and name it a import a, { b } from 'm' // Import the default export in module m and separately import member b import * as A from 'm' // Import all members in the module import 'm' // Execute m module export const b = 1 // Export separately export default b // Default export export { b } // Export on demand export { b as bb } // Rename and export export { b } from 'm' // Import member b in module m and export
ES2015 has added a new syntax for destructuring assignment, which allows us to use certain patterns in arrays. Or extract the specified value from the object.
The sample code is as follows:
// Destructuring assignment of array let [name, age, hobby = 'coding' /* Default value of structure assignment */] = ['A Bowl of Zhou', 18] // Swap the values of the two variables let a = 1 let b = 2 ;[a, b] = [b, a] console.log(a, b) // 2 1 // Object structure assignment let { name: ObjName /* Destructuring assignment rename*/, sex } = { name: 'A bowl of weeks', sex: 1 } // Destructuring assignment of function parameters function bar({ name, age }) { return name + age } bar({ name: 'A bowl of weeks', age: 18 }) // A bowl of weeks 18
Symbol is a new data type in ES2015. It is created through Symbol()
method and can pass a string as a parameter. Used to describe the Symbol;
the symbol values created through the Symbol() method are all unique. The sample code is as follows:
/** * Syntax * Symbol([description]) * * description -> is an optional description information */ //Create a value of type Symbol const mySymbol = Symbol() console.log(mySymbol) // Symbol() const myName = Symbol('A bowl of weeks') console.log(typeof myName) // symbol
Symbol also has a series of properties and methods that will not be introduced here.
Promise is an asynchronous solution provided in ES2015, which solves the problem of callback hell.
A promise object can be created through Promise()
constructor. Each Promise object has the following states:
There are only two types of state switching, namely:
. Once the state changes, it will not change again.
There is a then
method in the Promise
instance, allowing us to chain calls in the Promise
instance. Each then
method also has A Promise
instance will be returned,
as shown in the figure below:
The sample code is as follows:
new Promise((resolve, reject) => { console.log('I am the log in the first Promise') resolve() }) .then(() => { console.log('I am the log in the first then') }) .then(() => { console.log('I am the log in the second then, but I have an exception') throw new Error('Error') }) .then(() => { console.log('I am the log of the first callback in the third then, but I will not execute it because an exception occurred above me') }, () => { console.log('I am the log of the second callback in the third then, I executed it') }) .then(() => { console.log('I am the log in the fourth then, I can execute normally') }) /* The execution result is as follows: I am the log in the first Promise I am the log in the first then I am the log in the second then, but I got an exception. I am the log of the second callback in the third then. I executed it. I am the log in the fourth then. I can execute it normally*/
Related Some methods of Promise are as follows:
Promise.prototype.then()
: It requires at most two parameters: the callback function of Promise's success and failure;Promise.prototype.catch()
: equal to the second parameter of the then
method;Promise.all()
: Pack multiple instances into a new instance, return the result array after all instance status changes (change all changes and then return)Promise.race()
: Pack multiple instances into a new instance, return all instance status Prioritize the changed result (change first and return first)Promise.resolve()
: Convert the object to a Promise object (equivalent to new Promise(resolve => resolve())
)Promise.reject()
: Convert the object to a state of rejected
Promise object (equivalent to new Promise((resolve, reject) => reject())
)Iterator is an iterator. It is an interface that provides a unified access mechanism for various data structures. In other words, as long as any data structure deploys the iteration interface, it can be traversed in a unified way.
The data structure that implements the iterable interface generally implements itself or inherits the Symbol.iterator
attribute, and it is an iterable object. The Symbol.iterator
property itself is a function, which is the default iterator generation function of the current data structure.
An object that contains the next()
method can be called an iterable object. The next()
object will return an object containing two values,
as shown below:
value
: any JavaScript
value returned by the iterator. Can be omitted when done
is true
.done
: A Boolean value. When it is false
, it means that the iteration has not stopped. When it is true
, it stops the iterator immediately, and the value of value
can be omitted.The iterator interface provided natively by JavaScript is shown in the figure below:
Now we implement an iterator for obj, the code is as follows:
const obj = { [Symbol.iterator] () { return { next () { console.log('Iterator executed'); return { value: '', done: true // Flag whether it is over, true means it is over} } } } }
We added a print in the next()
method. In order to verify that the iterator was executed, the final running result is that
the iterator was executed.
Generator is an asynchronous programming solution provided in ES2015. The Generator function is defined in the function
keyword Use an *
asterisk between the function name and the function name, and use the yield
keyword inside the function to define different states.
The sample code is as follows:
function* testGenerator() { // yield defines a state yield 'a bowl of weeks' yield 'esnew features' return 'generator' // Terminate Generator, even if there is a yield keyword later, it will be invalid} const g = testGenerator() // Return the Generator object and move the state through the next() method g.next() /* { value: 'A bowl of Zhou', done: false } */ g.next() /* { value: 'es new features', done: false } */ g.next() /* { value: 'generator', done: true } */
Proxy objects are used to create a proxy object to implement interception and customization of basic operations. There are 13 basic operations, as shown in the following table:
Interception method The method | triggers |
---|---|
get(target, propKey, receiver) | to read a certain property |
set(target, propKey, value, receiver) | to write a certain property |
has(target, propKey) | in operator |
deleteProperty(target, propKey) | delete operator |
getPrototypeOf(target) | Object.getPropertypeOf() |
setPrototypeOf(target, proto) | Object.setPrototypeOf() |
isExtensible(target) | Object.isExtensible() |
preventExtensions(target) | Object.preventExtensions() |
getOwnPropertyDescriptor(target, propKey) | Object.getOwnPropertyDescriptor() |
defineProperty (target, propKey, propDesc) | Object.defineProperty() |
ownKeys(target) | Object.keys(), Object.getOwnPropertyNames(), Object.getOwnPropertySymbols() |
apply(target, thisArg, args) | calls a function |
construct(target, args) | Use new to call a function. |
Vue3 is written based on Proxy
. The following code shows the use of Proxy
objects:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet" /> <title>Automatically update dom through set</title> </head> <body> <p class="card" style="width: 300px; margin: 100px auto"> <p class="card-body"> <h1 id="name"></h1> <button id="btn" class="btn btn-primary">Modify</button> </p> </p> <script> // Get DOM node const name = document.getElementById('name') const btn = document.getElementById('btn') //Define a function that modifies the value const updateDOM = (el, value) => { el.innerHTML = value } const person = new Proxy({ name: 'A bowl of porridge', }, { set(target, propKey, value) { //If the value inside changes, call our updateDOM updateDOM(name, value) target[propKey] = value return true }, }) name.innerHTML = person.name // Click the button to trigger the modification operation btn.addEventListener('click', () => { person.name === 'A Bowl of Zhou'? (person.name = 'A bowl of porridge') : (person.name = 'One Bowl Zhou') }) </script> </body> </html>
The above code uses the set method for data binding. If the object changes, our DOM will be automatically updated.
Reflect is an object provided by ECMAScript2015. It provides some static methods for intercepting JavaScript operations. These methods are consistent with the methods in handlers
in Proxy.
Reflect is not a constructor, which means it cannot be instantiated.
Each interception operation in the Proxy
object (for example: get
, delete
, etc.) internally calls the Reflect
method accordingly. The static methods it provides are consistent with the method names in handlers
in Proxy,
as follows:
the default call | function |
---|---|
Reflect.get() | gets the value of a property on the object |
Reflect.has | |
on | the object |
() | Determine whether an object has a certain property |
Reflect.deleteProperty() | Delete the property on the object |
Reflect.getPrototypeOf() | Get the prototype of the specified object Function |
Reflect.setPrototypeOf() | Set or change the function of the object prototype |
Reflect.isExtensible() | Determine a Whether the object is extensible (that is, whether new properties can be added) |
Reflect.preventExtensions() | prevents new properties from being added to the object |
Reflect.getOwnPropertyDescriptor() | gets the property descriptor of a given property |
Reflect.defineProperty() | defines or modifies the properties of an object |
Reflect .ownKeys() | returns an array composed of the property keys of the target object itself. |
Reflect.apply() | calls a function, and at the same time, an array can be passed in as a calling parameter. |
Reflect.construct() | performs a new operation on the constructor to achieve creation. Instances of the class |
Set
, Map
, WeakSet
, and WeakMap
are several new objects in ES2015:
Set
and WeakSet
are similar to arrays. To be precise, they are sets. The difference between the two is that Set
can store Any data type, while WeakSet
can only store references to objects, and they are weak references;the most common use of Set objects in actual development is to implement data deduplication. The sample code is as follows:
const arr = [1, 2, 2, 3, 4 , 3, 5] const set = new Set(arr) // The set object can be used... to expand all items console.log([...set]) // [ 1, 2, 3, 4, 5 ]
Map
and WeakMap
are similar to objects and are stored in the form of key-value pairs Yes, the difference between the two is that the key-value pairs of Map
can be arbitrary, while the keys of WeakMap
must be references to objects and the values can be of any type.ES2016 releases relatively few new features, mainly two new features, as shown in the figure below:
ES2016 has a new exponent **
, also called the power operator, which has the same function as Math.pow().
The sample code is as follows:
console.log(2 ** 10 === Math.pow(2, 10 )) // true
adds the includes()
method to the array prototype in ES2016. This method is used to determine whether an array contains a specified value and returns a Boolean value.
The sample code is as follows:
const arr = [1, 2, 3, 4, 5, NaN] console.log(arr.indexOf(NaN)) // -1 console.log(arr.includes(NaN)) // true
It is worth noting that NaN
and NaN
, +0
and -0
are equal when using includes()
.
Promise solves the problem of callback hell, if there are too many chain calls, the readability will still become worse. The new async/await syntax sugar in ES2017 solves this problem.
Promise is written as follows:
;(function () { function promise(v) { return new Promise((resolve, reject) => { resolve(v) }) } const p = promise(1) p.then(res => { return promise(res) }).then(res => { console.log(res) }) })()
If the next Promise depends on the previous one, this chain of calls will be very long. Now let’s rewrite it using async/await syntactic sugar:
;(async function () { function promise(v) { return new Promise((resolve, reject) => { resolve(v) }) } const r1 = await promise(1) const r2 = await promise(r1) const res = await promise(r2) console.log(res) })()
As you can see, we can use async/await syntactic sugar to rewrite Promise into a flat writing method.
ES2017 adds a new Atomics object. This object provides a series of static methods for operating SharedArrayBuffer and ArrayBuffer objects. This object cannot be instantiated using the new
keyword. It only provides some static properties and method
. Three static methods have been extended for Object in ES2017, as follows:
Object.values()
: Returns an array of all enumerable property values of a given object itself;Object.entries()
: Returns an array of all enumerable property values of a given object itself. An array of key-value pairs for enumerated properties;Object.getOwnPropertyDescriptors()
: Returns the property descriptors of all the own properties of a given object.in ES2017 allows us to add a comma at the end of the function parameter list. This small feature is very useful, because only one line of code needs to be changed when updating the trailing comma. If the trailing comma is not applicable, two lines of code need to be changed.
The example code is as follows:
function fun( aaaaa, bbbbb, ccccc, ) {}
If there is a trailing comma, you only need to add a line at the end; if it does not exist, you need to add the comma at the end and then add a line. This changes two lines in version management, not one.
adds two new instance methods for strings in ES2017, which are:
padStart()
: fills spaces at the beginning of the string;padEnd()
: fills spaces at the end of the string;the sample code is as follows:
const str = ' A bowl of Zhou' console.log(str.padStart(10)) /* A bowl of Zhou*/ console.log(str.padEnd(10)) /* Yiwan Zhou*/
has a new for await...of
statement in ES2018, which can be used to traverse asynchronous iterable objects.
The sample code is as follows:
var asyncIterable = { [Symbol.asyncIterator]() { return { i: 0, next() { if (this.i < 3) { return Promise.resolve({ value: this.i++, done: false }) } return Promise.resolve({ done: true }) }, } }, } ;(async function () { for await (num of asyncIterable) { console.log(num) } })() // 0 // 1 // 2
In ES2018, the following extensions are made to regular expressions:
Regular expression group naming:
Before ES2018, we could not name the groups in regular expressions. This feature was introduced in ES2018. It not only facilitates regular reading and reference,
the sample code is as follows:
const RE_DATE = /(?<year>d{4})-(?<month>d{2})-(?<day>d {2})/ const matchObj = RE_DATE.exec('2022-02-22') const year = matchObj.groups.year // 2022 const month = matchObj.groups.month // 02 const day = matchObj.groups.day // 22
s modifier/dotALl mode: The new s modifier allows use .
Matches any single character, and the **** attribute indicates whether to use " s
" modification together in the regular expression symbol.
Reverse assertions: Only forward assertions existed before ES2018, while reverse assertions and reverse negative assertions were added in ES2018.
A new array spread operator was added in ES2015. In ES2018, this feature was added to the object. The sample code is as follows:
const n = { name: 'One Bowl of Zhou' } const a = { age: 18 } const person = { ...n, ...a } // Merge object console.log(person) // { name: 'A Bowl of Zhou', age: 18 }
finally()
method will return a Promise
object. When the state of the promise changes, whether If it becomes rejected
or fulfilled
, finally()
callback will be executed.
The sample code is as follows:
fetch(url) .then(res => { console.log(res) }) .catch(error => { console.log(error) }) .finally(() => { console.log('end') })
has optimized the following two contents in ES2019:
Function.prototype.toString()
: The returned function body contains comments and spaces;try...catch
: catch
in the statement allows no parameters. The sample code is as follows:try { console.log('A bowl of weeks') } catch { console.error('A bowl of weeks') }
String.prototype.trimStart
: used to remove spaces on the left side of the string;String.prototype.trimLeft
: it is an alias of trimStart
String.prototype.trimEnd
: used Remove the spaces on the right side of the string;String.prototype.trimRight
: It trimEnd
. Two array methods are extended in ES2019, namely:
Array.prototype.flat()
: This method will follow a specifiable Deeply recursively traverse the array and merge all elements with the elements in the traversed sub-array into a new array and return it; simply speaking, it is to achieve the flattening of the array.const arr = [0, 1, 2, [3, 4]] console.log(arr.flat()) // [ 0, 1, 2, 3, 4 ]
Array.prototype.flatMap()
: This method maps and flattens the array and returns a new array (only one level of array can be expanded ).The new Object.fromEntries()
method in ES2019 converts a list of key-value pairs into an object. It is the reverse operation of Object.entries()
method.
The sample code is as follows:
const person = { name: 'A Bowl of Zhou', age: '18', } const e = Object.entries(person) const p = Object.fromEntries(e) console.log(p) // { name: 'A bowl of weeks', age: '18' }
description
is a read-only property that returns the optional description string when creating the Symbol object .
Modularization
adds dynamic import in ES2020, which means that the module will be loaded when we need it. This can reduce overhead and page loading time. The sample code is as follows:
import('/modules/my-module.js'). then(module => { // Do something with the module. })
Dynamic import uses import()
method, which returns a Promise.
In ES2020, a meta
object is also added to import
, which exposes an object of context-specific metadata attributes to the JavaScript module.
BigInt solves the problem that the maximum number allowed in JavaScript is 2**53-1
. BigInt
can represent any large integer.
const theBiggestInt = 9007199254740991n; const alsoHuge = BigInt(9007199254740991); // ↪ 9007199254740991n const hugeString = BigInt("9007199254740991"); // ↪ 9007199254740991n const hugeHex = BigInt("0x1fffffffffffff"); // ↪ 9007199254740991n const hugeBin = BigInt("0b1111111111111111111111111111111111111111111111111111"); // ↪ 9007199254740991n
globalThis
was introduced in ES2020, which is the introduction of global objects. The global object in Node is Global
, and the browser environment is Window
; the following code shows the difference between whether there is GlobalThis
:
// before var getGlobal = function () { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('unable to locate global object'); }; var globals = getGlobal(); if (typeof globals.setTimeout !== 'function') { // no setTimeout in this environment! }
// after if (typeof globalThis.setTimeout !== 'function') { // no setTimeout in this environment! }
The null value coalescing operator is represented by two question marks. This operator is also a logical operator, which is similar to the logical OR operator. The calculation rule is that as long as the left operand is null
or undefined
, the right operand is returned, otherwise the left operand is returned. The logical OR operator only returns the right operand if the left operand is converted to boolean
type and is false
.
The sample code is as follows:
console.log(null ?? 10) // 10 console.log(undefined ?? 10) // 10 console.log(false ?? 10) // false
This operator is useful for assigning values to variables without values. For example: if this number has no value, assign it a value, otherwise do not assign a value.
The sample code is as follows:
var value // If the value of value is not null or undefined, assign it a value of 10 value = value ?? 10 console.log(value) // 10It
is worth noting that the null value coalescing operator and logical AND and logical OR cannot be used at the same time, otherwise an exception will be thrown. The solution is to indicate the priority by using
()
The optional chain operator is used to read the value of an attribute deep in the chain of an object. Using this operator does not need to verify that each attribute under the object must exist. For example, when we want to access the attribute Aab
, we first need to ensure that A
exists. , and then you need to ensure Aa
exists before you can access the attribute Aab
, otherwise an error will be reported.
Using the optional chain operator will not cause such a problem. When we access an attribute, as long as one part does not exist, undefind
will be returned and no error will be reported.
var A = {} // console.log(Aab) // Error console.log(Aa?.b) // The undefined
optional chain operator can also be used to call methods under objects. The sample code is as follows:
var obj = {} // If the obj.fun() method exists, it will be called directly below. If it does not exist, undefined will be returned. obj.fun?.A()
Promise.allSettled()
method returns a promise after all given promises have been resolved or rejected, with an array of objects, each object representing the corresponding promise. result.
replaceAll()
method returns a new string. The content of the new string has been replaced. The example code is as follows:
const str = 'A bowl of porridge' const newStr = str.replaceAll('porridge', 'week') console.log(newStr) // A bowl of
Strictly speaking, the numerical separator ( _
) does not belong to an operator. Its function is to make the numbers easier to read. For example, the following code
console.log(1_0000_0000) // The symbol 100000000
is only for ease of reading. The result of having or not does not affect it. See the code below
1_1 === 11 // true
The new WeakRef
object in ES2021 allows you to retain the reference to another object. Weak references will not prevent the weakly referenced object from being recycled by GC.
The new Promise.any()
method in ES2021 accepts the same parameters as promise.all()
The only difference is that there are no iterable objects accepted by the Promise.any()
method. If a promise succeeds (that is, all promises fail/reject), a failed promise and an instance of AggregateError type are returned.
Some new assignment operators have been added in ES2021, as follows:
&&=
||=
??=
In fact, it is consistent with the ordinary assignment operators. The sample code is as follows:
const [f1, f2, f3] = [ true, false] f1 &&= 'A bowl of weeks' // Equivalent to str = str && 'A bowl of weeks' f2 ||= 'A bowl of weeks' // Equivalent to str = str || 'A bowl of weeks' f3 ??= 'A bowl of weeks' // Equivalent to str = str ?? 'A bowl of weeks'
allows us to define class members without defining them in constructor
in ES2022. The sample code is as follows:
class C { myName = 'A Bowl of Zhou' } /* Both are consistent*/ class C { constructor() { myName = 'A Bowl of Zhou' } }
If a member is declared without initialization, its default value is undefined.
In ES2022, we are allowed to use variables named starting with #
as private members of the class.
The sample code is as follows:
class C { #myName = 'One bowl week' } const c = new C() console.log(#myName) // Private field '#myName' must be declared in an enclosing class
In ES2022, it is newly allowed to use await
at the top level. It can be wrapped at the top level without using async
function. Sample code As follows:
import { AsyncFun } from 'module' awaitAsyncFun() console.log(123)
Object.hasOwn()
method is used to determine whether an object has a certain attribute. The sample code is as follows:
const person = { name: 'A Bowl of Zhou', age: 18, } console.log(Object.hasOwn(person, 'name')) // true Console.log (Object.hasown (Person, 'Sex')) // false
ES2022 The newly added at()
method is to obtain a member of the array, its parameters
index
, it allows us to pass the negative value, which is the same as the countdown from the back.
console.log (Arr.at (-1)) // 6 // Equal to ARR [Arr.Length - 1]
regular expression adds one /d
modification symbol. When using the exec()
method of regular expression formula, if there is /d
modifier, the result will return more results to return more. An index attribute, which is used to represent the initial index value of the resulting result in the original string.
The example code is as follows:
const str = 'javascript' const R = /A /D const M = R.Exec (STR) Console.log (m.indices [0]) // [1, 2]
article is over. This article has compiled the new features of ES2015 to ES2022, and there may be omissions. Hope understanding.
The brain map is as follows: