簡(jiǎn)介
2015年6月正式發(fā)布ES6小泉,也稱為ES2015寿桨,此后的每一年都會(huì)進(jìn)行部分內(nèi)容進(jìn)行修訂并在6月發(fā)布對(duì)應(yīng)年號(hào)的ES版本始鱼,比如ES2016~ES2020济欢。ES2020是ECMAScript語(yǔ)言規(guī)范的第11版,也被稱為es11忆植。
ES2020特性(參考鏈接)
鏈合并運(yùn)算符
鏈?zhǔn)脚袛噙\(yùn)算符
如果讀取對(duì)象內(nèi)部的某個(gè)屬性放可,往往需要判斷一下該對(duì)象是否存在,比如獲取list.info.base.userName的值
// 錯(cuò)誤寫法朝刊,當(dāng)某一層級(jí)值為null或undefined時(shí)耀里,會(huì)報(bào)錯(cuò)
const userName = list.info.base.userName;
// 正確寫法(我們常用的方式)
const userName = (list && list.info && list.info.base && list.info.base.userName) || 'userName';
要取的userName處于對(duì)象的第三層,需要三層&&判斷才能取到值拾氓。
es2020
引入鏈合并運(yùn)算符冯挎,簡(jiǎn)化上面的寫法。
const userName = list?.info?.base?.userName || 'userName';
鏈合并運(yùn)算符
咙鞍,在調(diào)用的時(shí)候判斷左側(cè)的對(duì)象是否為null或undefined织堂。如果是的叠艳,就不再往下運(yùn)算,而是返回undefined易阳。
三種用法:
- obj?.prop // 對(duì)象屬性
- obj?.[expr] // 同上
- func?.(...args) // 函數(shù)或?qū)ο蠓椒ǖ恼{(diào)用
示例代碼
// obj?.prop
let list = {
info: {
// base: {
// userName: 'eyunhua'
// }
}
}
const userName = list?.info?.base?.userName || 'userName'; // 判斷?.左側(cè)表達(dá)式是否為null或undefined附较,否,則繼續(xù)往下運(yùn)算
// func?.(...args)
funtion register(a, b) {
console.log(a, b, 'register function');
}
this.register?.(1, 2); // register函數(shù)存在潦俺,則執(zhí)行此函數(shù)拒课,并且可傳參
// obj?.\[expr\]
let hex = "#C0FFEE".match(/#([A-Z]+)/i)?.[0];
console.log(hex);
Babel插件轉(zhuǎn)換
https://babeljs.io/docs/en/babel-plugin-syntax-optional-chaining
Null判斷運(yùn)算符
屬性值為null或undefined時(shí),指定默認(rèn)值
讀取對(duì)象屬性的時(shí)候事示,如果某個(gè)屬性的值是null或undefined早像,有時(shí)候需要為它們指定默認(rèn)值。常見(jiàn)做法是通過(guò)||運(yùn)算符指定默認(rèn)值肖爵。
const userName = (list && list.info && list.info.base && list.info.base.userName) || 'userName';
||
或運(yùn)算符表達(dá)的意思是左側(cè)表達(dá)式為null
卢鹦、undefined
、''
劝堪、false
冀自、0
,右側(cè)表達(dá)式都會(huì)生效秒啦。但我們想要的只是在null
或undefined
的時(shí)候生效熬粗。
es2020
引入了新的Null判斷運(yùn)算符??
。它的行為類似||
余境,但是只有運(yùn)算符左側(cè)的值為null
或undefined
時(shí)驻呐,才會(huì)返回右側(cè)的值。
與鏈判斷運(yùn)算符?.
配合使用芳来。
const userName = list?.info?.base?.userName ?? 'userName';
可用于函數(shù)參數(shù)默認(rèn)值的判斷
register(a, b) {
b = b ?? 3;
}
與&&
含末、||
運(yùn)算符一起使用時(shí),需要用括號(hào)來(lái)表明優(yōu)先級(jí)即舌,要不會(huì)報(bào)錯(cuò)答渔。優(yōu)先執(zhí)行括號(hào)括起來(lái)的部分
// 錯(cuò)誤
a && b ?? c
// 正確
(a && b) ?? c
這個(gè)運(yùn)算符的一個(gè)目的,就是跟鏈判斷運(yùn)算符?.
配合使用侥涵,為null
或undefined
的值設(shè)置默認(rèn)值。
Babel插件轉(zhuǎn)換
https://babeljs.io/docs/en/babel-plugin-proposal-nullish-coalescing-operator
import()
一種使用動(dòng)態(tài)說(shuō)明符異步導(dǎo)入模塊的語(yǔ)法
import
命令會(huì)被 JavaScript 引擎靜態(tài)分析宋雏,先于模塊內(nèi)的其他語(yǔ)句執(zhí)行芜飘。引擎處理import
語(yǔ)句是在編譯時(shí),而不是運(yùn)行時(shí)磨总。也就是說(shuō)import
和export
命令只能在模塊的頂層嗦明,而不能在代碼塊中。
假如我們要實(shí)現(xiàn)根據(jù)判斷引入模塊蚪燕,import命令是不可能實(shí)現(xiàn)的娶牌。
// 報(bào)錯(cuò)
if (page === 'home') {
import Home from './home';
}
ES2020提案引入import()
函數(shù)奔浅,支持動(dòng)態(tài)加載模塊
import(specifier) // specifier為加載模塊的位置或者腳本文件地址
import()
函數(shù)返回一個(gè)Promise對(duì)象,加載模塊成功以后诗良,這個(gè)模塊會(huì)作為一個(gè)對(duì)象汹桦,當(dāng)作then回調(diào)的參數(shù)。因此鉴裹,可以使用對(duì)象解構(gòu)賦值的語(yǔ)法舞骆,獲取輸出接口。
import(`./home.js`) // home.js中export const export1 = ''; ....
.then(({export1, export2})=>
// 加載成功的回調(diào)
})
.catch(err => {
// 加載失敗的回調(diào)
});
import()
是運(yùn)行時(shí)執(zhí)行径荔,也就是說(shuō)督禽,什么時(shí)候運(yùn)行到這一句,就會(huì)加載指定的模塊总处。另外狈惫,import()
函數(shù)與所加載的模塊沒(méi)有靜態(tài)連接關(guān)系,這點(diǎn)也是與import
語(yǔ)句不相同鹦马。import()
類似于Node
的require
方法胧谈,區(qū)別主要是前者是異步加載,后者是同步加載菠红。
適用場(chǎng)合
- 按需加載(比如點(diǎn)擊時(shí)加載某個(gè)文件或者模塊)
- 條件加載(比如if判斷模塊中)
- 動(dòng)態(tài)的模塊路徑(比如模塊路徑是實(shí)時(shí)生成)
Babel插件轉(zhuǎn)換
https://babeljs.io/docs/en/babel-plugin-syntax-dynamic-import
export * as ns from 'module'
在模塊內(nèi)使用的專用語(yǔ)法
在一個(gè)模塊內(nèi)第岖,先輸入模塊再輸出模塊, import
語(yǔ)句可與export
語(yǔ)句寫在一起试溯。
注意:
寫在一行后蔑滓,實(shí)際上并沒(méi)有導(dǎo)入接口,只是對(duì)接口進(jìn)行了轉(zhuǎn)發(fā)遇绞,導(dǎo)致在當(dāng)前模塊不能使用此接口键袱。
export { foo, bar } from 'my_module';
// 可以簡(jiǎn)單理解為
import { foo, bar } from 'my_module';
export { foo, bar };
es2020之前有一種import
復(fù)合寫法:
import * as someIdentifier from "someModule";
es2020引入對(duì)應(yīng)的export
寫法:
export * as someIdentifier from "someModule";
// 等同于
import * as ns from "mod";
export {ns};
Babel插件轉(zhuǎn)換
安裝插件@babel/plugin-proposal-export-namespace-from
npm install --save-dev @babel/plugin-proposal-export-namespace-from
在babel.cofig.js中添加plugin
{
"plugins": ["@babel/plugin-proposal-export-namespace-from"]
}
參考鏈接:
- https://github.com/tc39/proposal-export-ns-from
- https://babeljs.io/docs/en/babel-plugin-proposal-export-namespace-from
BigInt
一個(gè)用于處理任意精度整數(shù)的新數(shù)字基元
JavaScript 所有數(shù)字都保存成 64 位浮點(diǎn)數(shù),這給數(shù)值的表示帶來(lái)了兩大限制摹闽。
- 數(shù)值的精度:只能到 53 個(gè)二進(jìn)制位(相當(dāng)于 16 個(gè)十進(jìn)制位)蹄咖,大于這個(gè)范圍的整數(shù),JavaScript 是無(wú)法精確表示的付鹿。
- 大于或等于2的1024次方的數(shù)值澜汤,JavaScript 無(wú)法表示,會(huì)返回Infinity舵匾。
// 超過(guò) 53 個(gè)二進(jìn)制位的數(shù)值俊抵,無(wú)法保持精度
Math.pow(2, 53) === Math.pow(2, 53) + 1 // true
// 超過(guò) 2 的 1024 次方的數(shù)值,無(wú)法表示
Math.pow(2, 1024) // Infinity
關(guān)于js中最大的安全整數(shù)為什么是2的53次方減1坐梯?
為了更精確地表示沒(méi)有位數(shù)限制的整數(shù)徽诲,ES2020引入了不同于Number
數(shù)字類型的BigInt
數(shù)字類型, 只用來(lái)表示整數(shù)(大整數(shù)),沒(méi)有位數(shù)的限制
谎替,任何位數(shù)的整數(shù)都可以精確表示偷溺。為了與 Number 類型區(qū)別,BigInt 類型的數(shù)據(jù)必須添加后綴n
钱贯。
const a = 2172141653n;
const b = 15346349309n;
// BigInt 可以保持精度
a * b // 33334444555566667777n
// 普通整數(shù)無(wú)法保持精度
Number(a) * Number(b) // 33334444555566670000
typeof
運(yùn)算符對(duì)于BigInt數(shù)據(jù)類型挫掏,返回bigint
typeof 1n // bigint
Bigint對(duì)象
參考鏈接
JavaScript 原生提供BigInt對(duì)象,可以用作構(gòu)造函數(shù)生成 BigInt 類型的數(shù)值喷舀。轉(zhuǎn)換規(guī)則基本與Number()一致砍濒,將其他類型的值轉(zhuǎn)為 BigInt。
BigInt(123) // 123n
BigInt('123') // 123n
BigInt(false) // 0n
BigInt(true) // 1n
繼承的方法
// 繼承自其他對(duì)象的方法
BigInt.prototype.toString()
BigInt.prototype.valueOf()
BigInt.prototype.toLocaleString()
新增方法
BigInt.asUintN(width, BigInt)
: 給定的 BigInt 轉(zhuǎn)為 0 到 2width - 1 之間對(duì)應(yīng)的值硫麻。
BigInt.asIntN(width, BigInt)
:給定的 BigInt 轉(zhuǎn)為 -2width - 1 到 2width - 1 - 1 之間對(duì)應(yīng)的值爸邢。
BigInt.parseInt(string[, radix])
:近似于Number.parseInt(),將一個(gè)字符串轉(zhuǎn)換成指定進(jìn)制的 BigInt拿愧。
轉(zhuǎn)換運(yùn)算
參考鏈接
數(shù)學(xué)運(yùn)算
參考鏈接
其他運(yùn)算
參考鏈接
作為vue props使用---暫不支持
已經(jīng)在開(kāi)發(fā)中杠河,PR處于open狀態(tài)
https://github.com/vuejs/vue/pull/11191
Babel插件轉(zhuǎn)換
https://babeljs.io/docs/en/babel-plugin-syntax-bigint
Promise.allSettled
新的Promise組合器不會(huì)短路參考鏈接
該方法由 ES2020 引入。
接受一組 Promise 實(shí)例作為參數(shù)浇辜,包裝成一個(gè)新的 Promise 實(shí)例券敌。只有等到所有這些參數(shù)實(shí)例都返回結(jié)果,不管是fulfilled
還是rejected
柳洋,包裝實(shí)例才會(huì)結(jié)束待诅,一旦結(jié)束,狀態(tài)總是 fulfilled
熊镣,不會(huì)變成rejected
卑雁。狀態(tài)變成fulfilled
后,Promise 的監(jiān)聽(tīng)函數(shù)接收到的參數(shù)是一個(gè)數(shù)組绪囱,每個(gè)成員對(duì)應(yīng)一個(gè)傳入Promise.allSettled()
的 Promise
實(shí)例测蹲。
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: -1 }
// ]
監(jiān)聽(tīng)函數(shù)接收到的數(shù)組,每個(gè)成員都是一個(gè)對(duì)象鬼吵,對(duì)應(yīng)傳入Promise.allSettled()
的兩個(gè) Promise
實(shí)例扣甲。每個(gè)對(duì)象都有status
屬性,該屬性的值只可能是字符串fulfilled
或字符串rejected
齿椅。fulfilled
時(shí)琉挖,對(duì)象有value
屬性,rejected
時(shí)有reason
屬性涣脚,對(duì)應(yīng)兩種狀態(tài)的返回值示辈。
對(duì)比Promise.all
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello');
}, 1000);
}).then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('報(bào)錯(cuò)了');
}).then(result => result);
.catch(e => {
console.log('p2:' + e);
});
// const p = Promise.allSettled([p1, p2]);
const p = Promise.all([p1, p2]);
p.then(function (results) {
console.log(results);
}).catch(err => {
console.log('settled:' + err);
});
對(duì)比Promise.race
const p3 = new Promise((resolve, reject) => {
// setTimeout(() => {
resolve('成功了');
// }, 2000);
});
const race = Promise.race([
p3,
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 1000);
})
]);
race.then(data => {
console.log('success:', data);
}).catch(error => {
console.log('error:', error);
});
相同點(diǎn):
接受一組 Promise 實(shí)例作為參數(shù),包裝成一個(gè)新的 Promise 實(shí)例
不同點(diǎn):
- 狀態(tài)
Promise.all
- p1和p2實(shí)例狀態(tài)都為
fulfilled
時(shí)涩澡,p的狀態(tài)才會(huì)變成fulfilled
,此時(shí)p1、p2的返回值組成一個(gè)數(shù)組妙同,傳遞給p的回調(diào)函數(shù) - 只要p1射富、p2之中有一個(gè)被
rejected
,p的狀態(tài)就變成rejected
粥帚,此時(shí)第一個(gè)被reject的實(shí)例的返回值胰耗,會(huì)傳遞給p的回調(diào)函數(shù)
Promise.allSettled
一旦結(jié)束,狀態(tài)總是fulfilled
芒涡,不會(huì)變成rejected
(也就是永遠(yuǎn)進(jìn)不到p的catch回調(diào))柴灯。
Promise.race
其中一實(shí)例返回狀態(tài),p的狀態(tài)就會(huì)發(fā)生改變费尽,并且不會(huì)再變
- 返回值
Promise.all
返回?cái)?shù)組赠群,每一個(gè)成員都是實(shí)例對(duì)應(yīng)的結(jié)果
Promise.allSettled
返回?cái)?shù)組,數(shù)組的每一個(gè)成員都是對(duì)象旱幼,每個(gè)對(duì)象都有status
屬性查描,該屬性的值只可能是字符串fulfilled
或字符串rejected
。fulfilled
時(shí)柏卤,對(duì)象有value
屬性冬三,rejected
時(shí)有reason
屬性,對(duì)應(yīng)兩種狀態(tài)的返回值.
Promise.race
每一個(gè)實(shí)例對(duì)應(yīng)的結(jié)果
- 應(yīng)用場(chǎng)景
Promise.all
參數(shù)Promise實(shí)例中是否有被reject的實(shí)例缘缚,無(wú)法確定所有請(qǐng)求都已結(jié)束
Promise.allSettled
可以確定所有請(qǐng)求都已結(jié)束
Promise.race
只要有返回值勾笆,立馬停止其他請(qǐng)求
String.prototype.matchAll()
返回一個(gè)正則表達(dá)式在當(dāng)前字符串中所有的匹配
參考鏈接:
- https://es6.ruanyifeng.com/#docs/regex#String-prototype-matchAll
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll
ES2020之前
let regex = /t(e)(st(\d?))/g;
let string = 'test1test2test3';
let matches = [];
let match;
while (match = regex.exec(string)) {
matches.push(match);
}
console.log(matches); // 返回正則表達(dá)式在當(dāng)前字符串所有匹配(數(shù)組)
ES2020新增matchAll新特性
可一次性取出所有匹配,但是返回的是一個(gè)遍歷器(Iterator
)桥滨,而非數(shù)組窝爪。可以用for of
循環(huán)取出该园。
相對(duì)于返回?cái)?shù)組酸舍,返回遍歷器的好處在于,如果遍歷結(jié)果是一個(gè)很大的數(shù)組里初,那么遍歷器比較節(jié)省資源啃勉。
遍歷器轉(zhuǎn)換成數(shù)組,也是比較方便双妨,可以使用...
運(yùn)算符和Array.from()
就可以了淮阐。
let regex = /t(e)(st(\d?))/g;
let string = 'test1test2test3';
[...string.matchAll(regex)];
或
Array.from(string.matchAll(regex));
globalThis
一種在不同環(huán)境中獲取頂層對(duì)象的通用方式參考鏈接
不同環(huán)境中獲取全局對(duì)象的方法不同
- 瀏覽器里面,頂層對(duì)象是window刁品,但 Node 和 Web Worker 沒(méi)有window泣特。
- 瀏覽器和 Web Worker 里面,self也指向頂層對(duì)象挑随,但是 Node 沒(méi)有self状您。
- Node 里面,頂層對(duì)象是global,但其他環(huán)境都不支持
為了實(shí)現(xiàn)在不同環(huán)境中取到頂層對(duì)象膏孟,可采用下面三元表達(dá)式的方法實(shí)現(xiàn)眯分。
// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
// 方法二
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');
};
但這種方式相對(duì)比較麻煩、復(fù)雜柒桑。es2020
引入globalThis作為頂層弊决,在任何環(huán)境下都存在。