let variable declaration and declaration attributes
//Declare Variables let a; let b,c,d; let e=100; let f=521,g='iloveyou',h=[]; //1. Variables cannot be declared repeatedly let star='Luo Zhixiang' let star='Piglet*'//var can be declared repeatedly //2. Block-level Scope Global Function eval //3. There is no variable promotion //4. Does not affect scope chain { let school='Silicon Valley' function fn(){ console.log(school) } fn();//Looks up along the scope chain (block-level scopes do not affect the scope chain) }
const Declares Variables and Features
//declare constant const SCHOOL='Silicon Valley' //1. Be sure to assign an initial value const A; //2. Use uppercase for general constants //3. The value of a constant cannot be modified //4. Block-level Scope //5. Element modifications to arrays and objects are not counted as modifications to constants and will not cause errors const TEAM=['a','b'] TEAM.push('Meiko')//Think that the object pointed to by this variable has not changed
Deconstructive assignment of variables
ES6 allows you to extract values from arrays and objects in a pattern and assign values to variables
This is called deconstruction assignment
1. Deconstruction of Arrays
const HH=['a','b'] let [A,B]=HH //In this case A is a B is b; ------------------------------------- // ,= placeholder let arr = ["Xiao Ming", "Floret", "Small fish", "Piglet*"]; let [,,one] = arr; // Here's the little fish --------------------------------------- // Deconstruct the entire array let strArr = [...arr]; // Get the entire array console.log(strArr);
2. Deconstruction of Objects
const ZHAO={ name:'Solve' age:'60' haha:function(){ console.log("hhh") } } let {name,age,haha}=ZHAO; haha(); //Deconstruction must have the same name ------------------------------------------------------ // Remaining Operators let {a, b, ...demo} = {a: 1, b: 2, c: 3, d: 4}; // a = 1 // b = 2 // demo = {c: 3, d: 4} ------------------------------------------------------ let obj = { className : "Casino", age: 18 } let {className} = obj; // Get Casino let {age} = obj; // Get 18
Template String
How ES6 introduces a new declaration string``
//1. Declaration let str=`I am also a string` //2. Line breaks can appear directly in the content //3. Variable splicing let bala=`balabala`; let hh=`${bala}sss`; console.log(hh)//Output balabalasss // Call method in string function fn3(){ return "Handsome not!"; } let string2= `I am ${fn3 ()}`; console.log(string2); // I'm really handsome!
Simplified Writing of Objects
ES6 allows variables and functions to be written directly in curly brackets as attributes and methods of objects
This writing is more concise
let name='Silicon Valley'; let change=function(){ console.log('hhhh'); } //Concise writing const SCHOOL={ name, change,//Both globes can be abbreviated if they are identical improve(){ console.log('lllll') } }//The normal writing should be const SCHOOL={ name:name, change:change, improve:function(){ console.log('lllll') } }
Arrow functions and declarative features
ES6 allows functions to be defined using the [arrow]
//Declare a function let fn=function(){ } let fn=(a,b)=>{ return a+b; } //Call function let result=fn(1,2); console.log(result);
Characteristic:
- This is static, this always points to the value of this under the scope in which the function was declared (his this with call and apply will not change)
- Cannot be a constructed instance object
let Person=(name,age)=>{ this.name=name; this.age=age; } let me=new Person('xiao',30) Not allowed
3. You cannot use arguments variables
4. Short form of arrow function
- Omit parentheses when there is only one parameter
let add=n=>{ return n+n; } console.log(add(9));
- Omit curly brackets, when there is only one statement in the body of code, ** return must be omitted at this time, ** and the result of executing the statement is the return value of the function
let pow=n=> n*n; console.log(pow(9));
Scenarios for Arrow Functions
When we have code like this: let self = this;
When a new variable is needed to save this
Examples are as follows:
let Person1 = { 'age': 18, 'sayHello': function () { setTimeout(()=>{ console.log(this.age); }); } }; var age = 20; Person1.sayHello(); // 18
Arrow Function Use Cases
let ad = document.getElementById('ad') ad.addEventListener("click",function(){ setTimeout(()=>{ this.style.background='pink' },2000) });//This this is this when this function is declared, so it's ad; if you don't use the arrow function, this this points to window
//Filter out even elements in an array const arr=[1,6,9,10,100,25]; const result = arr.filter(item => item%2===0); console.log(result);
The arrow function is suitable for this-independent callbacks, timers, and array method callbacks
Arrow functions are not appropriate for this-related callbacks, event callbacks, object methods
Extension of function parameters
- Default parameters
// num is the default parameter and 10 if not passed function fn(type, num=10){ console.log(type, num); } fn(1); // Print 1,10 fn(1,2); // Print 1,2 (this value overrides the default parameter 10)
It is important to note that the default parameter is only used if the parameter is not passed or if it is undefined, and the null value is considered a valid value transfer.
2.Indefinite parameters
// The values here are variable, and no matter how many you pass function f(...values){ console.log(values.length); } f(1,2); // 2 f(1,2,3,4); // 4
rest parameter
ES6 introduces the rest parameter, which is used to get the argument of the function instead of argument
function fn(...args){ console.log(args) } fn('s''a''v'); //Returned is an array
The rest parameter must be placed at the end
function fn(a,b,...args){ }
Extension Operator
The extended operator converts an array to a comma-separated sequence of parameters
const abc=['a','b','c'] function change(){ console.log(arguments); } change(...abc)
Application of Extension Operators
1. Merge of Arrays
const ab=['a','b'] const cd=['c','d'] const abcd=[..ab,..cd];
2. Cloning of Arrays
const ab=['a','b'] const hh=[...ab]
3. Convert a pseudo array to a real array
Symbol
symbol Basic Usage
Symbol is the seventh data type in the js language and is a string-like data type
1. Its value is unique for resolving naming conflicts
2. Cannot operate with other data
3. You cannot traverse with a for...in loop, but you can use Reflect.ownKeys to get all the key names of objects
let s= Symbol(); let s2=Symbol('hhh') let s3=Symbol('hhh') console.log(s2===s3)//Return false //Symbol.for Establishment let s2=Symbol.for('hhh') let s3=Symbol.for('hhh') console.log(s2===s3)//Return true
iterator
//Declare an array const abcd=['a','b','c','d'] //Traversing an array using for..in for(let v in abcd){ console.log(v)//Output key name 0 1 2 3 } //Use for..of to traverse the array//iteration property with Symbol to use for(let v of abcd){ console.log(v)//Output key values a,b,c,d }
generator
A special kind of function
Implement asynchronous programming
Separator for yield function code
function * gen(){ console.log(111); yield '111'; console.log(222); yield '222'; console.log(333) }//console.log outputs yield ed content when there are no statements within the delimiter //Get Iterator Object let iterator=gen() iterator.next();//Output 111 iterator.next();//Output 222 iterator.next();//Output 333
Transfer of generator function parameters
The parameter passed in by the second next will be returned as the result of the first yield; and so on
Promise
Promise is a new solution to asynchronous programming introduced by ES6. Syntax Promise is a constructor that encapsulates asynchronous operations and can achieve their success or failure.
//Instantiate Promise Object const p=new Promise(function(resolve,reject){ setTimeout(function(){ { let data='Data in database' //resolve returned successfully resolve(data); //reject failed return let err='Data read failed'; reject(err); } },1000) }) //Call the then method of the promise object p.then(function(value){ console.log(value)//On success }),function(reason){ console.log(reason)//On Failure }
promise.prototype.then method
const p=new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('user data') //Success },1000) }) //The return result of calling the then method the method is a Promise object whose state is determined by the execution result of the callback function const result = p.then(value =>{ console.log(value); //1. If the result returned in the callback function is a property of type non-promise, the status is successful, and the return value is the success value of the object return 123; //2. is a promise object, then the value of the previous level of promise is the return value of this level return new Promise((resolve,reject)=>{ reject('errr') }) //3. Throw an error throw new Error('Error }),reason=>{ console.warn(reason) } console.log(result)
From what we found above, promise's chain call
p.then(value=>{ }).then(value=>{ })
Instances of Chain Calls
Read multiple files in a common nested way
const fs = require("fs"); fs.readFile('./resources/a.md',(err,data1)=>{ fs.readFile('./resources/b.md',(err,data2)=>{ fs.readFile('./resources/c.md',(err,data3)=>{ let result = data1 + data2 + data3; console.log(result); }) }) })
Then we implement it based on promise's chain call
const p = new Promise((resolve,reject)=>{ fs.readFile('./resources/a.md',(err,data)=>{ resolve(data) }) }) p.then(value=>{ //A promise is returned for nesting promises at this time return new Promise((resolve,reject)=>{ fs.readFile('./resources/b.md',(err,data)=>{ resolve([value,data]) //This encapsulates the previous level's successful return object value and the current object data to be returned into an array as the success value output }) }) }).then(value=>{//Here the value is the success of the last one return new Promise((resolve,reject)=>{ fs.readFile('./resources/c.md',(err,data)=>{ //Now press this data into the value value.push(data); resolve(value)//Return this value as a success value }) }) }).then(value=>{//This is the last then's success console.log(value.toString()) })
catch method for promise
const p = new Promise((resolve,reject)=>{ setTimeout (()=>{ reject("Error") },1000) })
conventional method
p.then(function(value){},function(reason){ console.error(reason) })
Method of catch
p.catch(function(reason){ console.warn(reason) })
Set
es6 provides a new data structure, Set (Set). It is similar to an array, but members have unique values. Collections implement the iterator interface, so they can be traversed using the Extended Operators and for...of...
let s=new Set() let s2=new Set(['a','b'])//Iterable data can be passed in console.log(s,typeof s)//Output Set{} Object
Properties and methods of sets
- size returns the number of elements in a set
- add adds a new element and returns the current collection
- Delete delet e element, return boolean value
- has detects if an element is in the collection, returns boolean
- clear Empty Collection
Instances of collections
let arr = [1,2,3,4,5,4,3,2,1]; //1. Array Weighting //Convert to a set, why does it weigh as its name implies, and then deconstruct it back into an array let result = [...new Set(arr)]; //2. Intersection let arr2=[4,5,6,5,6] //Remove weight first, then call filter filter let result = [...new Set(arr)].filter(item=>{ let s2=new Set(arr2);//Remove arr2 if(s2.has(item)){//If there is an item for the current loop in s2 return ture; }else{ return false; } }) //3. Union let union = [...new Set([...arr,...arr2])]; //4. Difference Set let arr2=[4,5,6,5,6] //Remove weight first, then call filter filter let result = [...new Set(arr)].filter(item=>{ let s2=new Set(arr2);//Remove arr2 if(s2.has(item)){//If there is an item for the current loop in s2 return false; }else{ return true; } })
Map
ES6 provides a Map data structure. It is similar to an object and a collection of key-value pairs. However, the range of keys is not limited to strings, and all types of values, including objects, can be used as key values and key names. Map also implements the iterator interface, so it can be traversed using Extended Operators and for...of....
let m = new Map(); Create an empty map
Map properties and methods:
- size returns the number of elements in a Map
- set adds a new element and returns the current Map
- get returns the key value of the key name object
- Delete delet e
- has detects if an element is included in the Map and returns a boolean value
- clear empties the collection and returns undefined
//Add elements (keys and values are parameters) m.set('name','Ha ha ha') m.set('change',function(){ console.log("Ha ha ha") }) let key = { school: } //Delete (key name is parameter) m.delet('name') //Obtain m.get('name') //Return key value //empty m.clear(); //ergodic for(let v of m){ console.log(v) //Returns an array [key name, key value] }
Class class
ES6 provides a more traditional way of writing, introducing the concept of Class as a template for objects. Classes can be defined by the class keyword. Essentially, ES6's class can be seen as just a grammatical sugar, and most of its functions can be achieved by ES5. The new class writing just makes the object prototype's writing clearer and more cattle.
ES5 Method
//Create function function Phone(brand,price){ this.brand=brand; this.price=price } //Add Method Phone.prototype.call=function(){ console.log("Phone") } //Instantiate Object let Huawei=new Phone('Huawei',5999) Huawei.call()//Output I can call
ES6 Method
class Phone{ //Construction method, name cannot be modified constructor(){//This method will be used automatically when new instantiates the object this.brand=brand; this.price=price; } //Method must use the following form of syntax and cannot use call:function(){} call(){ console.log("Well") } } let Huawei = new Phone("hh",5555)
Class static member
Function object and instance object properties are not identical, but prototype is identical
function Phone(){ //This is a function object } Phone.name='111' Phone.change = function(){ }//Add properties to the function object, where these two are equivalent to static objects Phone.prototype.call='1' let n = new Phone() //Create an instance object console.log(n.name)//Error will occur here console.log(n.call)//This will output 1
Presenting static objects with class es
class Phone{ static name='11' } let n = new Phone() console.log(n.name)//undefined console.log(Phone.name)//11
Class class inheritance (es5 inheritance view JS advanced documentation)
extends
super
class Phone{ //Construction method constructor(brand,price){ this.brand=brand; this.price=price; } //Member attributes of parent elements call(){ console.log("I can call") } } class SmartPhone extends Phone{ //Construction method constructor(brand,price,color,size){ super(brand,price)//Equivalent to Phone.call(this,brand,price) this.color=color this.size=size } photo(){ } play(){ } } const xiaomi = new SmartPhone('hhh',799,a,4) xiaomi.call()//Method of parent class can be invoked
Subclass Override of Parent Method
class Phone{ //Construction method constructor(brand,price){ this.brand=brand; this.price=price; } //Member attributes of parent elements call(){ console.log("I can call") } } class SmartPhone extends Phone{ //Construction method constructor(brand,price,color,size){ super(brand,price)//Equivalent to Phone.call(this,brand,price) this.color=color this.size=size } //These member methods cannot have super call(){ console.log("I can") } photo(){ } play(){ } } const xiaomi = new SmartPhone('hhh',799,a,4) xiaomi.call()//Output I can //Because the call method of the parent class is overridden in the subclass
Get and Set
Method binding of object's properties
class Phone{ get price(){ console.log("1") //<1> return "sss" } set price(newVal){//There must be a parameter console.log("hhh") } } //Instantiate Object let s = new Phone() console.log(s.price) //<2> //Will output 1 (this is console < 1 > output) and sss (this is console < 2 > output) s.price = 'free'; //hhh will be output (because the modification triggered the set method)
Gets usually encapsulate dynamic properties, such as mean or something
set for judgment, etc.
Numeric expansion
- Number.EPSILON is the minimum precision value represented by JavaScript
- Binary octal
- Number.isFinite detects whether a value returns a Boolean value for a finite number
- Number.isNaN detects whether a numeric value returns a Boolean value for NaN
- Number.parseInt Number.parseFloat string to integer
- Number.isInteger determines whether a number is an integer
- Math.trunc erases the decimal part of a number
- Math.sign returns 10 for positive and negative numbers, 0 for complex numbers, and -1 for negative and positive numbers
Object Method Extension
- Object.is determines whether two values are exactly equal and returns a Boolean value similar to===, but false when NaN===NaN and true when Object.is returns
- Merge of Object.assign objects returns a new object with the same name property that overrides the previous
- Object.setPrototypeOf Sets the prototype object Object.getPrototypeOf Modifies the prototype object
Modularization
Template functionality consists of two main commands: export and import
- The export command is used to specify the external interface of the template
- The import command is used to enter functionality provided by other templates
Basic methods of introducing modules
Introducing script tags in html
<script type="module"> import * as Variable Name from "File Address" </script>
Exposure in js file
export let school='sss' export function hh(){ console.log('11') }
Exposure Method
Separate Exposure
export let school='sss' export function hh(){ console.log('11') }
Unified Exposure
let school='sss' function hh(){ console.log('11') } export { school,hh }
** Default Exposure (** In the form of object attributes)
export default { school : 'hhh' change : function(){ console.log("jhhh") } } //The returned object is dafault
Introduction Method
Common Import Method
import * as Variable Name from "File Address"
Form of deconstruction assignment (should be exposed separately)
Introducing script tags in html
<script type="module"> import {school,hh} from "Corresponding file address" //When the name of a deconstructor is renamed, a new variable, such as school as s, can be assigned an as after the name //When exposing an object, be sure to assign it to a new variable </script>
Exposure in js file
export let school='sss' export function hh(){ console.log('11') }
Simple form (for default exposure)
import m3 from "address"
babel transformation and NPM packages
ES7 New Features
Array.prototype.includes
The includes method is used to detect whether an element is included in an array and return a Boolean type value
const arr = [1, 3, 5, 2, '8', NaN, -0] arr.includes(1) // true arr.includes(1, 2) // The second parameter of the false method represents the starting location of the search, which defaults to 0 arr.includes('1') // false arr.includes(NaN) // true arr.includes(+0) // true
Exponential operator
An exponential operator was introduced in ES7 with equivalent results to Math.pow()
console.log(2**10);// Output 1024zhicc console.log(Math.pow(2, 10)) // Output 1024
Async and Await
A combination of async and await syntax allows asynchronous code to be the same
Async
-
The async function returns a promise object, and callback functions can be added using the then method
-
The result of the promise object is determined by the return value of the async function
-
When a function executes, it returns when it encounters await, waits until the triggered asynchronous operation is complete, and then executes the statement following the body of the function.
Corresponding code status:
Await
To put it plainly, await is to make a acquisition of promise's successful objects, and to fail it is to try...catch
The expression on the right side of 1:await is generally a promise object, but it can also be other values
2: If the expression is a promise object, await returns the value of a promise success
3: If the expression is another value, use this value directly as the return value of await.
Be careful:
1:await must be written in the async function, but it may not be in the async function
2: If await's promise fails, it throws an exception and needs to be caught by try...catch
<script> async function main() { let p = new Promise((resolve, reject) => { resolve('OK'); }) // The case where await is promise on the right, so the value of resolution ('ok') above is returned let result = await p; console.log(result); } // Execute Function main(); </script>
Scenario 2: This is a rare case where the right side is usually a promise object
<script> async function main() { let p = new Promise((resolve, reject) => { resolve('OK'); }) // 1. The case where await is promise on the right, so the value of resolution ('ok') above is returned let result = await p; // 2.The right side of await is for other types of data, return whatever it is let result1=await 521; console.log(result1); } // Execute Function main(); </script>
Scenario 3: The right side of await is a failed promise
<script> async function main() { let p = new Promise((resolve, reject) => { // resolve('OK'); reject('Error'); }) try { let result3 = await p; }catch(error){ console.log(error); } } // Execute Function main(); </script>
Take a closer look at the Async and Await documentation
Object Method Extension
//Declare Object const school={ name:"hh", cities:["Foshan","Guangzhou"], subject:["Front end","java","Big data"] } //We can get the key value by the Object.keys() method console.log(Object.keys(school));//Output ['name','cities','subject'] //You can get the key name through the Object.values() method console.log(Object.values(school));//["hh",Array(2),Array(3)] //Names and values can be obtained from entries console.log(Object.entries(school)) //Return [['name','hh']['cities', Array(2)]['subject', Array(3)]] //Object.getOwnPropertyDescriptors() allows you to get a description object of the object's properties (the object is returned) console.log(Object.getOwnPropertyDescriptors(school)); //Return to {name:{...},cities:{...},subject:{...}
The entries method makes it easy to create a map
const m = new Map(Object.entries(school)); console.log(m.get('cities'));
Rest parameter and extension operator
rest parameter:... Parameter name
function connect({host,port,...user}){ console.log(host) console.log(port) console.log(user) } connect({ host:'111', port:3306, username:'hh', password:'123456' type:'boy' }) //Returns 111 3306 {username:'hh', password:'123456', type:'boy'}
Expand objects by...
const one={ q:'a' } const two={ w:'b' } const three={ e:'c' } const mengseng={...one,...two,...three} console.log(mengseng) //Output { q:'a', w:'b', e:'c' }
Regular Expansion
Named Snap Grouping
Prior to ES9, you needed to do this to get some values in the string
let str = '<a href="http://Www.baidu.com ">Baidu</a>" const reg = /<a href="(.*)">(.*)<\/a>/ let result = reg.exec(str) console.log(result)
ES9 allows named capture groups to use symbols? <name> to make capture results more readable
let str = '<a href="http://Www.baidu.com ">Baidu</a>" let reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/ let result = reg.exec(str) console.log(result) console.log(result.groups.url) console.log(result.groups.text)
Reverse Assertion
ES9 supports reverse assertions, uses?<=to judge what precedes the target content and fi lt er matches
let str = 'JS1231234 Hello A555 Haha' // Take out 555 // Forward Assertion, Judging Behind Target Content // const reg = /\d+(?=ha)/ // const result = reg.exec(str) // Reverse Assertion const reg = /(?<=ah)\d+/ const result = reg.exec(str)
dotAll mode
In regular expressions. Matches any single character except carriage return, marker s changes this behavior, allowing line terminators to appear
let str = `<ul> <li> <a>the shawshank redemption</a> <p>Release date: 1994-09-10</p> </li> <li> <a>Forrest Gump</a> <p>Release date: 1994-07-06</p> </li> </ul>` // const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>\s+<\/li>/g const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs; let result; let data = [] while (result = reg.exec(str)) { data.push({ title: result[1], time: result[2] }) } console.log(data)
ES10 Object New Features
object.fromEntries
This method is used to create objects, but it is special because the parameter passed in is either a two-dimensional array or a Map object
Here's a demonstration of a two-dimensional array
const result = Object.fromEntries([ ["name","rht"], ["object","Math","English"] ]) console.log(result) //Return Object { name:"rht", object:"Math,English" }
The following demonstrates how Map works
const m = new Map() m.set('name','HHHH') const result = Object.fromEntries(m) console.log(result) //Return Object { name:"HHHH" }
Object.entries (inverse of fromEntries)
entries is the inverse of fromEntries, which converts an object into a two-dimensional array
const arr = Object.entries({ name:"hhhh", b:"a" }) console.log(arr) //Returns a two-dimensional array [["name","hhhh"],["b","a"]]
ES10 String New Method
trim
Characters used to clear blanks on both sides of a string
trimStart
Use to clear blanks at the beginning of a string
trimEnd
Clears the blanks at the end of the string
ES10 Array Method
flat Decreases Array Dimension
flat can reduce the dimension of an array by one, two to one, three to two
const arr=[1,2,3,[4,5]] console.log(arr.flat) //Return [1,2,3,4,5]
Flat passes a parameter, num, as the depth. When a three-dimensional array is going to become a one-dimensional array directly, reduce the two dimensions, then the depth is 2, that is, the parameter should be 2
flatMap reduces the dimension of a map
ES11 New Features
BigInt
We know that the range of safe integers js can represent is - (2^53-1) to 2^53-1, which is determined by how js stores numbers. We can use Number.isSafeInteger() to determine whether a number is within this range, and the upper and lower boundaries can be obtained with Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER.
es11 introduced a new data type, BigInt, to solve the problem of large numbers. This data type can perform large integer operations, but note that BigInt and ordinary Number types cannot perform operations.
BigInt can be obtained by using the constructor of BigInt or by appending a suffix n to the number.
let a = BigInt(123); let b = 1212n; let a = Number.MAX_SAFE_INTEGER; console.log(a + 1 === a + 2); //true let b = 9007199254740992n; let c = b + 1n; b === c; //false typeof b; //bigint
If BigInt and normal Number data are computed, an error will be reported
let d = 1n; d + 1;//Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
String.prototype.matchAll
The matchAll method of a string instance receives a regular or string and returns an iterator, which returns a match and corresponding matching information each time it executes. We can iterate through the iterator to get all the results
var str = '<div>JS</div><div>regular</div>'; var allMatchs = str.matchAll(/<\w+>(.*?)<\/\w+>/g); for (const match of allMatchs) { console.log(match); } /* The first iteration returns: [ "<div>JS</div>", "JS", index: 0, input: "<div>JS</div><div>regular</div>", groups: undefined ] The second iteration returns: [ "<div>regular</div>", "regular", index: 15, input: "<div>JS</div><div>regular</div>", groups: undefined ]
globalThis
Because js has different running environments, different running environments have different global objects, such as global in node, window s or self in browser. In order to obtain global objects in a unified way, there is globalThis. GlobalThis points to the same object as the global objects in each environment, but only standardizes the acquisition method.
GlobalThis//window (browser environment)
dynamic-import
This feature is supported in both webpack s and ts, that is, dynamic loading, or on-demand loading.
Import (src) returns a promise object, so it can be handled with await or a registered callback
async function fn() { const a = await import("./7-1.js"); import("./7-1.js").then((module) => { // }); }
Another point to note is that previous imports can only be written in the top-level scope, not inside a function, but now dynamic imports can be written in non-top-level scopes.
Null Value Merge Operator
This feature has been in use for half a year since version 3.7 of ts. The null value merge operator (??) is a bit like the previous or (||) operators. The difference is that when the expression on the left is false (0, ", NaN, null, undefined), the value on the right is taken, while the null value merge operator is null (undifined) in the expression on the left.Take the value on the right.
Take an example:
const a = 0; const b = false; const c = null; const d = undefined; console.log(a || b); //false console.log(a ?? c); //0 console.log(c ?? d); //undefined
Optional Chaining
This feature was also introduced as early as version 3.7 of ts and is often used with null value merge operators.
When we point out attributes or methods with objects, if nested, it is possible that an intermediate object is undifined, resulting in code errors. For code robustness, we often use &&to avoid, for example:
a && a.b && a.b();
With the null value merge operator, there is no need for redundant &&.
a?.b?.()
Arrays can be viewed as special objects, also used when fetching array members?
b?.[1]?.ccc//Possible ccc attributes of the possible second member of the b array
Null merge operators combined with optional chains make it easy to assign values to a variable and default values on assignments that fail
const a = b?.c?.d ?? "";
Promise.allSettled
We know that Promise.all is used to trigger callbacks after all promise instances have resolve d. The problem is that if a promise fails, reject, then the state of Promise.all fails, that is, it does not trigger the first parameter as a callback function. To complement this scenario, Promise.Setalltled comes.
Promise.allSettled also receives a Promise array as a parameter when all parameter states are complete (success or failure)The callback function has two attributes for each element of the array, one is status, the value is'rejected'or'fullfilled', which corresponds to whether the promise succeeds or fails, and the other is reason, which indicates the callback parameter of promise.
const a1 = Promise.resolve(1); const a2 = Promise.resolve(2); const a3 = Promise.reject(3); const a4 = Promise.reject(); Promise.allSettled([a1, a2, a3, a4]).then((a) => { console.log(a); }); // [ // { "status": "fulfilled", "value": 1 }, // { "status": "fulfilled", "value": 2 }, // { "status": "rejected", "reason": 3 }, // { "status": "rejected", "reason": undefined} // ]
Aggregate Export
With respect to import, we can import all members as follows:
import * as MyModule from '...'
A companion has been added this time
export * as MyModule from '...'
This export statement serves the same purpose as the following statement
import * as MyModule from '...' export {MyModule}
These are the new features of ES11, you can see that the speckle changes are larger than those of previous ES10, which also facilitates the writing of some js code.