ES is ECMAScript, a standardized scripting language developed by ECMA. The current version of ECMAScript used by JavaScript is ECMA-417. For the latest information about ECMA, visit ECMA News.
The ECMA specification is finalized by TC39. TC39 is a group of parties, including browser vendors, that meet to push JavaScript proposals along a strict development path. There are several main stages from proposal to ECMA specification:
- Stage 0: Strawman — Submission of initial ideas.
- Stage 1: Proposal — A formal proposal document initiated by at least one TC39 member that includes API instances.
- Stage 2: Draft — The initial version of the functional specification, which contains two experimental implementations of the functional specification.
- Stage 3: Candidate — The proposal specification is reviewed and feedback is gathered from the vendor
- Stage 4: Finished — The proposal is ready for ECMAScript, but it may take longer to get to the browser or Nodejs.
New ES6 Features (2015)
ES6 has a lot of features, and it was only standardized nearly six years after ES5 was released (2009-11 to 2015-6). There’s a lot of time between releases, so there are a lot of features in ES6. Here are a few common ones:
- class
- modular
- Arrow function
- Default values for function arguments
- Template string
- Deconstruction assignment
- Extension operator
- Shorthand for object property
- Promise
- Let the Const
1. Class
For developers familiar with Java, Object-C, C # and other pure object-oriented languages, class will have a special feeling. ES6 introduced classes to make object-oriented programming in JavaScript much simpler and easier to understand.
class Animal {
// The constructor that will be called when instantiated, if not specified, will have a default constructor with no arguments.
constructor(name,color) {
this.name = name;
this.color = color;
}
// toString is a property on the stereotype object
toString() {
console.log('name:' + this.name + ',color:' + this.color); }}var animal = new Animal('dog'.'white');// Instantiate Animal
animal.toString();
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true
class Cat extends Animal {
constructor(action) {
// Subclasses must specify the super function in constructor, otherwise an error will be reported when creating an instance.
// Constructor with the default super function will be added if the top consructor is not set.
super('cat'.'white');
this.action = action;
}
toString() {
console.log(super.toString()); }}var cat = new Cat('catch')
cat.toString();
// the instance cat is an instance of cat and Animal, which is identical to Es5.
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
Copy the code
2. Module
ES5 does not support native modularity, and modules are added as an important part of ES6. The functions of the module mainly consist of export and import. Each module has its own scope. The calling relationship between modules is to specify the interfaces exposed by the module through export, and to refer to the interfaces provided by other modules through import. Namespaces are also created for modules to prevent naming conflicts for functions.
Export (export)
ES6 allows you to export multiple variables or functions within a module using export.
Export variables
//test.js
export var name = 'Rainbow'
Copy the code
Note: ES6 not only supports the export of variables, but also supports the export of constants. export const sqrt = Math.sqrt; // Export the constant
ES6 treats a file as a module that exports a variable through export. A module can also output multiple variables simultaneously.
//test.js
var name = 'Rainbow';
var age = '24';
export {name, age};
Copy the code
The export function
// myModule.js
export function myModule(someArg) {
return someArg;
}
Copy the code
Import (import)
Once the output of a module is defined, it can be referenced in another module by import.
import {myModule} from 'myModule';// main.js
import {name,age} from 'test';// test.js
Copy the code
Note: An import statement can import both default functions and other variables. import defaultMethod, { otherMethod } from ‘xxx.js’;
3. Arrow function
This is one of the most exciting features in ES6. => It’s not just shorthand for the keyword function, but it has other benefits as well. The arrow function shares the same “this” with the code surrounding it, which helps you solve the “this” problem. Experienced JavaScript developers are familiar with things like var self = this; Or var that = this. But with =>, you don’t need this model.
The structure of the arrow function
The arrow => of an arrow function is preceded by an empty parenthesis, a single argument name, or multiple argument names enclosed in parentheses. The arrow can be followed by an expression (as the return value of the function), or by the body of the function enclosed in curly braces (the value must be returned by return itself; otherwise, undefined).
// Example of the arrow function() = >1
v=>v+1
(a,b)=>a+b
()=>{
alert("foo");
}
e=>{
if (e == 0) {return 0;
}
return 1000/e;
}
Copy the code
Note: Both the arrow function and bind return a new function reference each time they are executed, so if you need the function reference to do something else (such as unmount a listener), you must keep the reference yourself.
Trap when uninstalling listeners
Wrong way
class PauseMenu extends React.Component{
componentWillMount(){
AppStateIOS.addEventListener('change'.this.onAppPaused.bind(this));
}
componentWillUnmount(){
AppStateIOS.removeEventListener('change'.this.onAppPaused.bind(this));
}
onAppPaused(event){
}
}
Copy the code
The right thing to do
class PauseMenu extends React.Component{
constructor(props){
super(props);
this._onAppPaused = this.onAppPaused.bind(this);
}
componentWillMount(){
AppStateIOS.addEventListener('change'.this._onAppPaused);
}
componentWillUnmount(){
AppStateIOS.removeEventListener('change'.this._onAppPaused);
}
onAppPaused(event){
}
}
Copy the code
In addition to the above, we can do the following:
class PauseMenu extends React.Component{
componentWillMount(){
AppStateIOS.addEventListener('change'.this.onAppPaused);
}
componentWillUnmount(){
AppStateIOS.removeEventListener('change'.this.onAppPaused);
}
onAppPaused = (event) = > {
// Define the function directly as a property of the arrow function, which is initialized with the this pointer bound}}Copy the code
Note that both bind and arrow functions return a new function reference each time they are executed, so if you need the function reference to do something else (such as unmount listeners), you must save the reference yourself.
4.Default values for function arguments
ES6 supports setting default values for functions when they are defined:
function foo(height = 50, color = 'red')
{
// ...
}
Copy the code
Default values are not used:
function foo(height, color)
{
var height = height || 50;
var color = color || 'red';
/ /...
}
Copy the code
This is usually fine, but it becomes problematic when the parameter’s Boolean value is false. For example, we call foo like this:
foo(0, "")
Copy the code
Since the Boolean value of 0 is false, the height will be 50. Similarly, the value of color is’ red ‘.
Therefore, function parameter defaults can not only make the code cleaner but also avoid some problems.
5. Template characters
ES6 supports template strings, which makes concatenation of strings more concise and intuitive.
Do not use template strings:
var name = 'Your name is ' + first + ' ' + last + '. '
Copy the code
Using a template string:
var name = `Your name is ${first} ${last}. `
Copy the code
String concatenation is done in ES6 with ${}, just by putting variables in curly braces.
6.Deconstruction assignment
Destruct assignment syntax is an expression in JavaScript that allows you to quickly extract values from an array or object and assign them to a defined variable.
Gets the value in the array
We get values from the array and assign them to variables in the order that corresponds to the order of objects in the array.
var foo = ["one"."two"."three"."four"];
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
// If you want to ignore some values, you can get the values you want as follows
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"
// You can also write like this
var a, b; // Declare variables first
[a, b] = [1.2];
console.log(a); / / 1
console.log(b); / / 2
Copy the code
If you don’t get a value from the array, you can set a default value for the variable.
var a, b;
[a=5, b=7] = [1];
console.log(a); / / 1
console.log(b); / / 7
Copy the code
Deconstructing assignments makes it easy to exchange the values of two variables.
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); / / 3
console.log(b); / / 1
Copy the code
Gets the value in the object
const student = {
name:'Ming'.age:'18'.city:'Shanghai'
};
const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); 18 "/ /"
console.log(city); // "Shanghai"
Copy the code
7. Spread operator
The extension operator… Array expressions or strings can be expanded syntactically during function calls/array construction; You can also expand an object expression as a key-value when an object is constructed.
grammar
Function call:
myFunction(... iterableObj);Copy the code
An array construct or string:
[...iterableObj, '4'.'hello'.6];
Copy the code
Cloning or copying properties when constructing objects (new to the ECMAScript 2018 specification) :
letobjClone = { ... obj };Copy the code
Application scenarios
Use the extension operator when a function is called
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1.2.3];
// Do not use the extension operator
console.log(sum.apply(null, numbers));
// Use the extension operator
console.log(sum(... numbers));/ / 6
Copy the code
Constructing an array
Push, splice, concat, and other methods can be used to make the elements of an existing array part of a new array without expansion syntax. With the expansion syntax, constructing new arrays becomes simpler and more elegant:
const stuendts = ['Jine'.'Tom'];
const persons = ['Tony'. stuendts,'Aaron'.'Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]
Copy the code
Similar to the argument list expansion,… It can be used multiple times in any location when constructing a word group.
Copy an array
var arr = [1.2.3];
var arr2 = [...arr]; // equivalent to arr.slice()
arr2.push(4);
console.log(arr2)/ / [1, 2, 3, 4]
Copy the code
The expansion syntax behaves the same as object.assign (), executing a shallow copy (traversing only one level).
Concatenating arrays
var arr1 = [0.1.2];
var arr2 = [3.4.5];
var arr3 = [...arr1, ...arr2];// Append all elements of arR2 to arR1 and return
/ / is equivalent to
var arr4 = arr1.concat(arr2);
Copy the code
Extended operators have added support for objects in ECMAScript 2018
var obj1 = { foo: 'bar'.x: 42 };
var obj2 = { foo: 'baz'.y: 13 };
varclonedObj = { ... obj1 };// Clone object: {foo: "bar", x: 42}
varmergedObj = { ... obj1, ... obj2 };{foo: "baz", x: 42, y: 13}
Copy the code
Application in React
Usually when we encapsulate a component, we expose props to implement the functionality. Pass props that should be displayed externally in most cases. But when passing a large number of props can be tedious, we can use… (the extension operator, which retrives all the traversable properties of the parameter object).
Normally we would write it like this
<CustomComponent name ='Jine' age ={21} / >Copy the code
The use of… That’s the same thing as the above
const params = {
name: 'Jine'.age: 21} <CustomComponent {... params} />Copy the code
Cooperate with destruct assignment to avoid passing unnecessary parameters
var params = {
name: '123'.title: '456'.type: 'aaa'
}
var{ type, ... other } = params; <CustomComponent type='normal' number={2} {... <CustomComponent type='normal' number={2} name='123' title='456' />Copy the code
8. Shorthand for object properties
ES6 allows you to set a property of an object without specifying the property name.
Do not use the ES6
const name='Ming',age='18',city='Shanghai';
const student = {
name:name,
age:age,
city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
Copy the code
Objects must contain properties and values, which is very redundant.
Use the ES6
const name='Ming',age='18',city='Shanghai';
const student = {
name,
age,
city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
Copy the code
Object, which is very concise.
9.Promise
Promise is a more elegant solution to asynchronous programming than the traditional callback solution. It was first proposed and implemented by the community, and ES6 wrote it into the language standard, unifying usage and providing Promise objects natively.
Do not use the ES6
Nest two setTimeout callbacks:
setTimeout(function()
{
console.log('Hello'); // Output "Hello" after 1 second
setTimeout(function()
{
console.log('Hi'); // Output "Hi" after 2 seconds
}, 1000);
}, 1000);
Copy the code
Use the ES6
var waitSecond = new Promise(function(resolve, reject)
{
setTimeout(resolve, 1000);
});
waitSecond
.then(function()
{
console.log("Hello"); // Output "Hello" after 1 second
return waitSecond;
})
.then(function()
{
console.log("Hi"); // Output "Hi" after 2 seconds
});
Copy the code
The above code uses two THEN’s for asynchronous programming serialization, avoiding callback hell:
10. Support let and const
Previously, JS did not have a block-level scope. Const and let fill this convenient gap. Const and let are block-level scopes.
Variables defined using var are at function level scope:
{
var a = 10;
}
console.log(a); / / output 10
Copy the code
Variables defined with let and const are block-level scoped:
{
let a = 10;
}
console.log(a); //-1 or Error "ReferenceError: a is not defined"
Copy the code
New ES7 Features (2016)
ES2016 added two small features to illustrate the standardization process:
- The array includes() method, which determines whether an array contains a specified value, returning true if it does, false otherwise.
- The a ** b exponent operator, which is the same as Math.pow(a, b).
1.Array.prototype.includes()
The includes() function determines whether an array contains a specified value, returning true if it does, and false otherwise.
The includes function is similar to indexOf. The following two expressions are equivalent:
arr.includes(x)
arr.indexOf(x) >= 0
Copy the code
Next, we determine whether the number contains an element:
What we did before ES7
Use indexOf() to verify the presence of an element in the array, depending on whether the return value is -1:
let arr = ['react'.'angular'.'vue'];
if (arr.indexOf('react')! = =- 1)
{
console.log('the react there');
}
Copy the code
Use ES7 includes()
Use includes() to verify the presence of an element in the array for a more intuitive purpose:
let arr = ['react'.'angular'.'vue'];
if (arr.includes('react'))
{
console.log('the react there');
}
Copy the code
2. Exponential operator
In ES7, the exponent operator ** was introduced, ** has the same function as math.pow (..) Equivalent calculation result.
Do not use the exponential operator
Use the custom recursive function calculateExponent or math.pow () to calculate the exponent:
function calculateExponent(base, exponent)
{
if (exponent === 1)
{
return base;
}
else
{
return base * calculateExponent(base, exponent - 1); }}console.log(calculateExponent(2.10)); / / output 1024
console.log(Math.pow(2.10)); / / output 1024
Copy the code
Use the exponential operator
Use the exponent operator **, just like the +, -, and so on:
console.log(2六四事件10);/ / output 1024
Copy the code
New ES8 Features (2017)
- async/await
Object.values()
Object.entries()
- String padding:
padStart()
andpadEnd()
To fill the string to the current length - A comma is allowed at the end of the function argument list
Object.getOwnPropertyDescriptors()
ShareArrayBuffer
andAtomics
Object for reading and writing from shared memory locations
1.async/await
ES2018 introduces asynchronous iterators, which are just like regular iterators except that the next() method returns a Promise. So await can be combined with for… Of loop to run asynchronous operations in a serial manner. Such as:
async function process(array) {
for await (let i ofarray) { doSomething(i); }}Copy the code
2.Object.values()
Object.values() is a new function similar to object.keys (), but returns all the values of the property of the Object itself, excluding inherited values.
Suppose we want to traverse all the values of the following object obj:
const obj = {a: 1.b: 2.c: 3};
Copy the code
Do not use object.values () :ES7
const vals=Object.keys(obj).map(key= >obj[key]);
console.log(vals);/ / [1, 2, 3]
Copy the code
Use the Object. The values () : ES8
const values=Object.values(obj1);
console.log(values);/ / [1, 2, 3]
Copy the code
As you can see from the code above, object.values () saves us the step of going through keys and getting values from them.
3.Object.entries()
The object.entries () function returns an array of key-value pairs for the enumerable properties of a given Object itself.
Next, let’s iterate over the keys and values of all properties of the obj object:
Do not use object.entries () :ES7
Object.keys(obj).forEach(key= >{
console.log('key:'+key+' value:'+obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3
Copy the code
The use of the Object. Entries () : ES8
for(let [key,value] of Object.entries(obj1)){
console.log(`key: ${key} value:${value}`)}//key:a value:1
//key:b value:2
//key:c value:3
Copy the code
4.String padding
In ES8 two instances have been added to the String String. The function prototype. PadStart and String prototype. PadEnd, allows you to an empty String or other String is added to the beginning or end of the original String.
String.padStart(targetLength,[padString])
- TargetLength: the targetLength to which the current string is to be filled. If this value is less than the length of the current string, the current string itself is returned.
- PadString :(optional) padding a string. If the string is so long that the length of the filled string exceeds the target length, only the leftmost part is retained and the rest is truncated. The default value of this parameter is “”.
console.log('0.0'.padStart(4.'10')) / / 10.0
console.log('0.0'.padStart(20))/ / 0.00
Copy the code
String.padEnd(targetLength,padString])
- TargetLength: the targetLength to which the current string is to be filled. If this value is less than the length of the current string, the current string itself is returned.
- PadString :(optional) padding a string. If the string is so long that the length of the filled string exceeds the target length, only the leftmost part is retained and the rest is truncated. The default value of this parameter is “”.
console.log('0.0'.padEnd(4.'0')) / / 0.00
console.log('0.0'.padEnd(10.'0'))/ / 0.00000000
Copy the code
5. Allow a comma at the end of the function argument list
The main effect is to make it easier to modify the same function when using Git for collaborative development and reduce unnecessary row changes.
6.Object.getOwnPropertyDescriptors()
Object. GetOwnPropertyDescriptors () function is used to retrieve an Object of all their property descriptors, if you don’t have any own properties, it returns null objects.
Function prototype:
Object.getOwnPropertyDescriptors(obj)
Copy the code
Returns a descriptor for all self properties of an obj object, or an empty object if there are none.
const obj2 = {
name: 'Jine',
get age() { return '18'}};Object.getOwnPropertyDescriptors(obj2)
/ / {
// age: {
// configurable: true,
// enumerable: true,
// get: function age(){}, //the getter function
// set: undefined
/ /},
// name: {
// configurable: true,
// enumerable: true,
// value:"Jine",
// writable:true
/ /}
// }
Copy the code
7. SharedArrayBuffer object
SharedArrayBuffer objects are used to represent a generic, fixed-length buffer of raw binary data, similar to ArrayBuffer objects, and both can be used to create views in shared memory. Unlike ArrayBuffer, SharedArrayBuffer cannot be detached.
/** ** @param {*} length Size of the array buffer to be created, in bytes. * @returns {SharedArrayBuffer} A new SharedArrayBuffer of a specified size. Its contents are initialized to 0. * /
new SharedArrayBuffer(length)
Copy the code
8. Atomics object
The Atomics object provides a set of static methods for atomizing SharedArrayBuffer objects.
These atomic operations belong to the Atomics module. Unlike a normal global object, Atomics is not a constructor and therefore cannot be called using the new operator or directly as a function. All of Atomics’ properties and methods are static (just like the Math object).
Multiple threads of shared memory can simultaneously read and write data in the same location. An atomic operation ensures that the value of the data being read or written is as expected, that the next atomic operation will not start until the last one has finished, and that its operation will not be interrupted.
- Atomics.add()
Adds the array elements at the specified position to the given value and returns the value of the element before the addition.
- Atomics.and()
Aligns the array element at the specified position with the given value and returns the value of the element before the operation.
- Atomics.compareExchange()
If the specified element in the array is equal to the given value, it is updated to the new value and the original value of the element is returned.
- Atomics.exchange()
Updates the specified element in the array to the given value, and returns the value before the element was updated.
- Atomics.load()
Returns the value of the specified element in the array.
- Atomics.or()
Aligns an array element at the specified position with the given value, and returns the value of the element before the or operation.
- Atomics.store()
Sets the specified element in the array to the given value and returns that value.
- Atomics.sub()
Subtracts an array element at the specified position from the given value and returns the value of that element before subtraction.
- Atomics.xor()
Differentiates or from the given value an array element at the specified position, and returns the value of the element before the xOR operation.
The wait() and wake() methods use the Linux Futexes model (fast user-space mutex) to make a process wait until a particular condition is true, and are mainly used for blocking.
- Atomics.wait()
Detects whether the value at a specified position in the array is still the given value, and if so, remains suspended until awakened or timed out. The return value is “OK”, “not-equal”, or “time-out”. When called, an exception is thrown if the current thread is not allowed to block (most browsers do not allow wait() to be called on the main thread).
- Atomics.wake()
Wakes up the threads in the wait queue that are waiting on the element at the specified location in the array. The return value is the number of threads that were successfully awakened.
- Atomics.isLockFree(size)
Can be used to detect whether the current system supports hardware-level atomic operations. Return true for an array of specified size if the current system supports hardware-level atomic operations. Otherwise, this means that for the array, each atomic operation in the Atomics object can only be implemented with a lock. This function is aimed at technical experts. –>
New ES9 Features (2018)
- Asynchronous iterative
- Promise.finally()
- Rest/Spread properties
- Regular Expression Named Capture Groups
- Regular expression reverse assertion (lookbehind)
- Regular expression dotAll pattern
- Regular expression Unicode escapes
- A template string that is not an escape sequence
1. Asynchronous iteration
At some point in async/await, you may try to call an asynchronous function in a synchronous loop. Such as:
async function process(array) {
for (let i of array) {
awaitdoSomething(i); }}Copy the code
This code won’t work, and neither will the following:
async function process(array) {
array.forEach(async i => {
await doSomething(i);
});
}
Copy the code
In this code, the loop itself remains synchronized and is fully called before the internal asynchronous function.
ES2018 introduces asynchronous iterators, which are just like regular iterators except that the next() method returns a Promise. So await can be combined with for… Of loop to run asynchronous operations in a serial manner. Such as:
async function process(array) {
for await (let i ofarray) { doSomething(i); }}Copy the code
2.Promise.finally()
A Promise call chain either successfully reaches the last.then(), or fails to trigger.catch(). In some cases, you want to run the same code, such as clear, delete conversations, close database connections, and so on, whether the Promise runs successfully or fails.
.finally() allows you to specify the final logic:
function doSomething() {
doSomething1()
.then(doSomething2)
.then(doSomething3)
.catch(err= > {
console.log(err);
})
.finally((a)= > {
// finish here!
});
}
Copy the code
3. The Rest/Spread properties
ES2015 introduces Rest parameters and extension operators. Three points (…) Arrays only. Rest parameter syntax allows us to represent an indefinite number of parameters as an array.
restParam(1.2.3.4.5);
function restParam(p1, p2, ... p3) {
// p1 = 1
// p2 = 2
// p3 = [3, 4, 5]
}
Copy the code
The expansion operator works in reverse, converting the array into individual arguments that can be passed to the function. For example, math.max () returns the maximum value of a given number:
const values = [99, 100, -1, 48, 16]; console.log( Math.max(... values) ); / / 100Copy the code
ES2018 provides the same Rest parameters () and expansion operators for object destructuring as arrays. A simple example:
const myObject = {
a: 1.b: 2.c: 3
};
const{ a, ... x } = myObject;// a = 1
// x = { b: 2, c: 3 }
Copy the code
Or you can use it to pass arguments to functions:
restParam({
a: 1.b: 2.c: 3
});
function restParam({ a, ... x }) {
// a = 1
// x = { b: 2, c: 3 }
}
Copy the code
As with arrays, Rest parameters can only be used at the end of the declaration. In addition, it only applies at the top level of each object, not if there are nested objects in the object.
Extension operators can be used within other objects, such as:
const obj1 = { a: 1.b: 2.c: 3 };
constobj2 = { ... obj1,z: 26 };
// obj2 is { a: 1, b: 2, c: 3, z: 26 }
Copy the code
You can copy an object using an extension operator like obj2 = {… Obj1}, but this is only a shallow copy of the object. In addition, if an object A has an attribute of object B, then in the cloned object cloneB, that attribute points to object B.
4. The regular expression is used to name the capture group
JavaScript regular expressions can return a matching object — a class-like array of matching strings, for example: parse a date in the format YYYY-MM-DD:
const
reDate = / [0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) /,
match = reDate.exec('2018-04-30'),
year = match[1]./ / 2018
month = match[2].// 04
day = match[3]; / / 30
Copy the code
This code is hard to read, and changing the structure of the regular expression can change the index of the matched object.
Does ES2018 allow named capture groups to use symbols?
, after opening the capture parenthesis (immediately after naming, as shown in the following example:
const
reDate = / (?
[0-9]{4})-(?
[0-9]{2})-(?
[0-9]{2})/
,
match = reDate.exec('2018-04-30'),
year = match.groups.year, / / 2018
month = match.groups.month, // 04
day = match.groups.day; / / 30
Copy the code
Any named group that fails to match will return undefined.
Named capture can also be used in the replace() method. For example, to convert a date to the U.S. format MM-DD-YYYY:
const
reDate = / (?
[0-9]{4})-(?
[0-9]{2})-(?
[0-9]{2})/
,
d = '2018-04-30',
usDate = d.replace(reDate, '$<month>-$<day>-$<year>');
Copy the code
5. Regular expression reverse assertion
JavaScript currently supports lookahead in regular expressions. This means that a match occurs, but there is no capture, and the assertion is not included in the entire match field. For example, to capture a currency symbol from a price:
const
reLookahead = /\D(? =\d+)/,
match = reLookahead.exec('$123.89');
console.log( match[0]);/ / $
Copy the code
ES2018 introduces a reverse assertion that works the same way but matches the previous lookbehind, so I can ignore the currency sign and simply capture the number of prices:
const
reLookbehind = / (? <=\D)\d+/,
match = reLookbehind.exec('$123.89');
console.log( match[0]);/ / 123.89
Copy the code
The above is the affirmative reverse assertion that the non-number \D must exist. Similarly, there are negative reverse assertions, which indicate that a value must not exist, such as:
const
reLookbehindNeg = / (?
,
match = reLookbehind.exec('$123.89');
console.log( match[0]);// null
Copy the code
6. Regular expression dotAll mode
Midpoint of a regular expression. Matches any single character except carriage return. The s flag changes this behavior to allow line terminators, such as:
/hello.world/.test('hello\nworld'); // false
/hello.world/s.test('hello\nworld'); // true
Copy the code
7. Regular expression Unicode escapes
Until now, local access to Unicode character properties in regular expressions has not been allowed. ES2018 added Unicode attribute escapes — form \p{… } and \ {P… }, using the u (Unicode) tag in the regular expression, and within the \p block, you can set the attribute to match as a key-value pair rather than the actual content. Such as:
const reGreekSymbol = /\p{Script=Greek}/u;
reGreekSymbol.test('PI.); // true
Copy the code
This feature improves readability and maintainability by avoiding the use of specific Unicode ranges for content type determination.
8. Template strings that are not escape sequences
Before, \u starts a Unicode escape, \x starts a hexadecimal escape, \ followed by a number starts an octal escape. This makes it impossible to create specific strings, such as Windows file path C:\uuu\ XXX \111. Refer to the template string for more details.
New ES10 Features (2019)
- Line delimiter (U + 2028) and segment delimiter (U + 2029) symbols are now allowed to match JSON within string literals
- More friendly json.stringify
- Added Array
flat()
Methods andflatMap()
methods - Added String
trimStart()
Methods andtrimEnd()
methods Object.fromEntries()
Symbol.prototype.description
String.prototype.matchAll
Function.prototype.toString()
Now return exact characters, including Spaces and comments- To simplify the
try {} catch {}
, modifycatch
The binding - New basic data types
BigInt
- globalThis
- import()
- Legacy RegEx
- Private instance methods and accessors
1. Line delimiter (U + 2028) and segment delimiter (U + 2029) symbols are now allowed to match JSON within string literals
Previously, these symbols were treated as line terminators in string literals, so their use would result in a SyntaxError exception.
2. More friendly json. stringify
If you enter a character in Unicode format but out of range, the original json. stringify returns an ill-formed Unicode string. A Phase 3 proposal that changes json.stringify is now implemented, so it outputs an escape sequence for it, making it valid Unicode (and represented as UTF-8)
3. Array is addedflat()
Methods andflatMap()
methods
Flat () and flatMap() are essentially reduce and concat operations.
Array.prototype.flat()
The flat() method recurses through the array at a specified depth and returns a new array combining all the elements with the elements in the subarray it traverses.
flat()
Method is basically used to reduce the dimension of an array
var arr1 = [1.2[3.4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1.2[3.4[5.6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1.2[3.4[5.6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
// Expand the nested array of any depth, using Infinity as the depth
arr3.flat(Infinity);
// [1, 2, 3, 4, 5, 6]
Copy the code
- Secondly, it can be used
flat()
Method to remove empty items from an array
var arr4 = [1.2.4.5];
arr4.flat();
// [1, 2, 4, 5]
Copy the code
Array.prototype.flatMap()
The flatMap() method first maps each element using a mapping function, and then compresses the result into a new array. It is almost identical to a map and a flat with a depth value of 1, but flatmaps are usually slightly more efficient at merging into one method. Here we compare the map method with the flatMap method.
var arr1 = [1.2.3.4];
arr1.map(x= > [x * 2]);
// [[2], [4], [6], [8]
arr1.flatMap(x= > [x * 2]);
// [2, 4, 6, 8]
// Only flatters the array returned by the function in flatMap
arr1.flatMap(x= > [[x * 2]]);
// [[2], [4], [6], [8]
Copy the code
4. Added StringtrimStart()
Methods andtrimEnd()
methods
These two new methods are easy to understand, removing whitespace characters at the beginning and end of the string, respectively, so I don’t need to use an example here.
5.Object.fromEntries()
The object.entries () method returns an array of key-value pairs for enumerable properties of a given Object, arranged in parallel with the for… The in loop returns the same order as it traverses the object (the difference is that the for-in loop also enumerates properties in the prototype chain).
whileObject.fromEntries()
It isObject.entries()
The reverse.
The object.fromentries () function passes in a list of key-value pairs and returns a new Object with them. The iteration argument should be an object that implements the @iterator method, returning an iterator object. It generates an array-like object with two elements, the first being the value to be used as the property key, and the second being the value associated with the property key.
- Using object.fromentries, you can convert a Map to an Object:
const map = new Map([['foo'.'bar'], ['baz'.42]]);const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
Copy the code
- Using object. fromEntries, you can convert an Array to an Object:
const arr = [ ['0'.'a'], ['1'.'b'], ['2'.'c']].const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
Copy the code
6.Symbol.prototype.description
When creating a Symbol using the factory function Symbol (), you can choose to provide a string as a description as an argument:
const sym = Symbol('The description');
Copy the code
Previously, the only way to access the description was to convert the symbol to a string:
assert.equal(String(sym), 'Symbol(The description)');
Copy the code
Now the introduction of the getter Symbol. The prototype. The description with direct access to the description:
assert.equal(sym.description, 'The description');
Copy the code
7.String.prototype.matchAll
The matchAll() method returns an iterator containing all the results of the matched regular expression and the group capture. Before matchAll appears, all matches are obtained by calling regexp.exec in the loop (regexp uses the /g flag:
const regexp = RegExp('foo*'.'g');
const str = 'table football, foosball';
while((matches = regexp.exec(str)) ! = =null) {
console.log(`Found ${matches[0]}. Next starts at ${regexp.lastIndex}. `);
// expected output: "Found foo. Next starts at 9."
// expected output: "Found foo. Next starts at 19."
}
Copy the code
If you use matchAll, you don’t need to use the while loop and exec mode (and regular expressions need to use the/g flag). Using matchAll returns an iterator, paired with for… Of, array spread, or array. From () can be more convenient to implement:
const regexp = RegExp('foo*'.'g');
const str = 'table football, foosball';
let matches = str.matchAll(regexp);
for (const match of matches) {
console.log(match);
}
// Array [ "foo" ]
// Array [ "foo" ]
// matches iterator is exhausted after the for.. of iteration
// Call matchAll again to create a new iterator
matches = str.matchAll(regexp);
Array.from(matches, m => m[0]);
// Array [ "foo", "foo" ]
Copy the code
MatchAll is better for grouping
var regexp = /t(e)(st(\d?) )/g;
var str = 'test1test2';
str.match(regexp);
// Array ['test1', 'test2']
Copy the code
let array = [...str.matchAll(regexp)];
array[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]
Copy the code
8.Function.prototype.toString()
Now return exact characters, including Spaces and comments
function/ *comment* /foo/ *another comment* /) {}
// The comments section will not be printed before
console.log(foo.toString()); // function foo(){}
// ES2019 will print the comments together
console.log(foo.toString()); // function /* comment */ foo /* another comment */ (){}
// Arrow function
const bar /* comment */ = /* another comment */() = > {};console.log(bar.toString()); / / () = > {}
Copy the code
9. Modifycatch
The binding
Prior to ES10, we had to bind an exception variable to a catch clause via syntax, whether it was necessary or not. Many times catch blocks are redundant. The ES10 proposal allows us to simply omit variables.
Not a big change.
Before is
try {} catch(e) {}
Copy the code
Now it is
try {} catch {}
Copy the code
10. New basic data typesBigInt
There are now more than five basic data types (value types) (six after ES6). There are seven basic data types: String, Number, Boolean, Null, Undefined, Symbol, BigInt
ES6, ES7, and ES8 Study Guide