原文地址:https://dev.to/bhagatparwinder/8-features-from-es2020-es11-you-should-know-1n9
ES2020(ES11)规范今年(作者写文章那年)发布了,它引入了不少新特性,我们一起来学习一下新规范中的 8 个关键亮点特性。
动态引入
Babel 和 Webpack 允许我们有条件的把 JavaScript 文件作为模块引入到应用中。动态引入现在原生支持了。这个特性被用来提高代码分割和按需加载代码(允许懒加载)。
例子:
我们假设你有一个 greeting 模块,接收 name 作为参数同时打印出 name 相关的问候信息。
export const greeting = (name) => console.log(`Hello ${name}`);
你可以有条件的引入到应用中:
const time = "morning"; // this is dynamically set to the time of day, hardcoded for example
if (time === "morning") {
const say = await import("./greeting.js");
say.greeting("Parwinder"); // Hello Parwinder
}
私有类变量
我之前的博文中提到过私有变量和方法,让我们一起来看下例子:
class ObjectCreator {
#meaningOfLife;
constructor(name) {
this.#meaningOfLife = 42;
}
returnMeaningOfLife() {
return this.#meaningOfLife;
}
#returnAMessage() {
return "You will do great things in life";
}
}
const myObject = new ObjectCreator("Parwinder");
console.log(myObject.returnMeaningOfLife()); // 42
console.log(myObject["#meaningOfLife"]); // undefined
console.log(myObject.#meaningOfLife); // SyntaxError
console.log(myObject.#returnAMessage); // SyntaxError
语言层面进行了封装,在作用域之外引用 #
相关的属性则会报错。全局和私有字段不会冲突,在同一个类中可以同时存在私有或私有的 #meaningOfLife
字段。
可选链
JavaScript 中获取对象属性是一个常见操作,多数时候这些属性是嵌套的。当你从一个不存在的对象上获取属性时 JavaScript 就会报错。
?.
操作符在对象上执行属性获取。在链式获取属性时,可选链不是抛出错误而是遇到第一个 undefined/null 时尽快的结束并返回 undefined
。
const myObject = {
name: "Parwinder",
car: "Cybertruck",
age: 42,
computers: {
first: {
name: "iMac",
year: 2017,
spec: {
cpu: "i7",
ram: "16GB"
}
},
second: {
name: "MacBook Pro"
}
}
}
console.log(myObject.computers.first.spec.cpu); // i7
console.log(myObject.computers.second.spec.cpu); // Cannot read property 'cpu' of undefined
我们可以通过使用可选链来解决 cpu
的访问错误。
myObject?.computers?.second?.spec?.cpu // undefined
// Concise and easy to read code
// or
myObject.computers.second.spec?.cpu
Promise.allSettled
之前文章已经介绍过,这里就只写例子:
const promise1 = Promise.resolve("Parwinder");
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve("Lauren");
}, 2000);
});
const promise3 = Promise.reject("Robert");
const promise4 = Promise.resolve("Eliu");
Promise.allSettled([promise1, promise2, promise3, promise4]).then((data) => {
console.log(data);
});
一旦上面四个 promise 结束,allSettled
会把结果传递到 then 的 callback 中,打印如下:
[{
status: "fulfilled",
value: "Parwinder"
}, {
status: "fulfilled",
value: "Lauren"
}, {
reason: "Robert",
status: "rejected"
}, {
status: "fulfilled",
value: "Eliu"
}]
String.prototype.matchAll()
matchAll
是 String 原型上的新方法,它使我们可以把字符串与正则进行匹配,然后返回一个 iterator 对象代表所有匹配的结果。
const input = 'Hello Andy, Where is Beth? Emily was asking for her.';
const regex = /[A-E]/g;
const matches = input.matchAll(regex);
console.log([...matches][0]);
// [
// 0: "A"
// groups: undefined
// index: 6
// input: "Hello Andy, Where is Beth? Emily was asking for her."
// ]
globalThis
根据代码执行环境不同,我们使用不同语法来获取全局对象,在浏览器中,我们使用 window
、self
、frame
,但在 Web Workers 中,我们只能使用 self
。在 Node 中又完全不同,我们只能使用 global
。
globalThis
的目的就是提供一个标准的获取全局对象的方法:
console.log(globalThis); // Window {...} for browsers
console.log(globalThis); // Object [global] {...} for Node
console.log(globalThis); // DedicatedWorkerGlobalScope {...} for Web Workers
BigInt
BigInt
是一个数值类型,供我们可以使用任意长度的整数(比 2**53 - 1
或 9007199254740991 还大的数)。
我们通过在整数尾部添加 n
或 调用 BigInt()
来创建 BigInt
类型整数。
const bigint = 9879846412313194464434496849n;
const bigintByMethod = BigInt("9879846412313194464434496849");
console.log(bigint); // 9879846412313194464434496849
console.log(bigintByMethod); // 9879846412313194464434496849
console.log(bigint === bigintByMethod); // true
console.log(typeof bigint); // bigint
console.log(typeof bigintByMethod); // bigint
const bigintFromExisting = BigInt(25);
console.log(bigintFromExisting); // 25
console.log(typeof bigintFromExisting); // bigint
空值合并运算符
??
运算符当其左侧的值为 null
或 undefined
时返回其右侧的值,反之返回左侧的值。
const luckyNumber = 0 ?? 42;
console.log(luckyNumber); // 0
const employeeName = null ?? "Parwinder";
console.log(employeeName); // Parwinder
注意:??
操作符在 false
或 NaN
并不起作用,这就是它与 ||
的区别。||
总是返回可转为真值的值,而 ??
操作符则返回非空的值。