ECMAScript 2020(ES11)新特性,不是所有特性都被现代浏览器支持,故还是需要加入Babel进行编译;新特性兼容性
Optional Chaining 可选链式调用
场景:某些情况下知道值会存在,直接引用会报错,使用可选链式操作符即可避免该错误,使用一个问号和一个点组成
用处: 可用于接口数据返回时判断;
// object
let a = {};
console.log(a.b); // undefiend
console.log(a.b.c); //Uncaught TypeError: Cannot read property 'c' of undefined
//es11
console.log(a.b?.c) // undefiend
//array
let m = [1];
console.log(m[0]); // 1
m = null
console.log(m[0]); // Uncaught TypeError: Cannot read property '0' of null
//es11
console.log(m?.[0]); // undefiend
//function
let x = () => {return 'func'};
console.log(x()); // func
x = null;
console.log(x()); //Uncaught TypeError: x is not a function
// es11
console.log(x?.()); // undefined
Nullish Coalescing 空值合并
场景: 为变量提供回退值,通常使用操作符||
,适用于大多数情况,但也有些特殊场景,如变量值为布尔值或数字时,如当前值为0时,使用es11??
双问号合并操作符即可检查变量是否未数字或布尔值;
用处: 用于变量回退值为特殊场景下的值,如变量值为布尔值或数字
let a = 1;
let b = a || -1; // 1
a = 0;
b = a || -1 // -1,但此时a是一个正常值范围,只不过为0
// es11
b = a ?? -1 // 0
let x = true;
let y = x || true; // true
x = false;
y = x || true; // true,但此时x只是一个为false的布尔值
// es11
y = x ?? true; // false
Private Fields 私有字段
场景: 在别的oo语言早就有类的语法,且可以定义类的公有(public)、私有(private)和受保护(protected)属性,但是在javasctipt中,es6才支持类的语法,es11开始支持私有字段,之前定义私有属性,都是通过加_
来伪定义;
用处:es11中可在属性前使用散列符号#
来定义私有属性;
class Theme {
#const_color = 'red';
constructor(color) {
this.color = color;
}
getColor() {
return this.#const_color
}
}
let theme = new Theme('white');
console.log(theme.color); // white
console.log(theme.getColor); // red
//es11,直接调用私有方法报错
console.log(theme.#const_color); // Uncaught SyntaxError: Private field '#const_color' must be declared in an enclosing class
Static Fields 静态字段
场景: 使用类的方法,必须实例化一个类
用处: 使用static
字段,类可以被static
关键词声明然后从外部调用
class Theme {
constructor(color) {
this.color = color;
}
getColor() {
return this.color
}
static get_color(color) { // 其实也只是个语法糖而已。。
return new Theme(color);
}
}
let theme = new Theme('white');
theme.getColor(); // white
Theme.getColor(); // Uncaught TypeError: Theme.getColor is not a function
Theme.get_color('white'); //Theme {color: "white"}
Top Levek Await 顶级Await
场景: 当前await获取promise结果,需要使用async关键字,全局作用下,只能使用立即调用的函数表达式(IIFE)
用处: 使用顶级Await后,不需要把代码包裹在async函数中
// IIFE
(async () => {
const result = await fetch(url);
})()
// es11
const Lg = await import(`/i18n/${language}`);
let vue
try {
vue = await import('vue-url');
}
catch {
vue = await import('vue-url2);
}
但顶层await也有一些弊端,如:
阻断执行
阻断资源请求
仅限于ES模块,不支持脚本或commonjs模块
stage 3 的提案
同级之间可以执行,最终不会阻断; 顶层 await 发生在模块图的执行阶段。至此,所有资源均已获取并链接。没有阻塞获取资源的风险;
顶层 await 仅限于 ES 模块。明确不支持脚本或 CommonJS 模块
Promise.allSettled方法
场景:多个promise请求,可以使用promise.all,但如果其中一个请求失败,则会抛出错误,有些场景下可能希望及时一个请求失败,其他结果能正常返回;
用处: 使用ES11 Promise.allSettled方法,成功会返回一个包含status和vaule的对象,失败则会返回一个status和reason的对象
let promise1 = Promise.resolve('hello');
let promise2 = new Promise((resolve, reject) => setTimeout(reject, 200, 'problem'));
Promise.all([promise1, promise2]).then(([res1, res2]) => {
console.log(res1, res2)
}); //Promise {<rejected>: "problem"}
// es11
Promise.allSettled([promise1, promise2]).then(([res1, res2]) => {
console.log(res1, res2)
}); // {status: "fulfilled", value: "hello"} {status: "rejected", reason: "problem"}
Dynamic Import 动态导入
import('/xx/xx.js').then(res => res.method());
使用普遍的webpack已经支持模块打包器来进行代码的转义和优化;
matchAll 匹配所有项
let regexp = /t(e)(st(\d?))/g;
let str = 'test1test2';
let array = [...str.matchAll(regexp)];
console.log(array);
//["test1", "e", "st1", "1", index: 0, input: "test1test2", groups: undefined], ["test2", "e", "st2", "2", index: 5, input: "test1test2", groups: undefined]
globalThis 全局对象
Javascript可以在浏览器或nodejs中运行,浏览器中的全局对象是window
, nodejs中是global
,为了统一,es11中引入globalThis
;
// 浏览器
window == globalThis // true
// node.js
global == globalThis // true
BigInt
js能够表达的最大数字时2^53-1, BigInt可以创建更大的数字
const evenBiggerNumber = BigInt(9007199254740991);