安装
由于许多人的浏览器版本低,我们需要使用babel来让用户使用无法使用的特性。为了简单起见,我将使用
Parcel bundler使一切尽快运行。
$ yarn add parcel-bundler
"scripts": {
"start": "parcel index.html"
},
不幸的是,现在似乎还没有ES2020的有效预设。 如果将它们放在
.babelrc文件中并保存,Parcel应该会为您安装所有内容
{
"plugins": [
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-private-methods",
"@babel/plugin-syntax-bigint"
]
}
-
可选链运算符 - Optional Chaining
有时候为了访问深层嵌套的属性,我们需要写一个很长的&&链去检查每个属性是否存在,代码如下:
var price = result && result.body && result.body.data && result.body.data.price;事实上在日常开发中我们经常要这么做,而且如果我们不这么做,那么很可能导致程序异常。为了简化上述的代码,于是乎新增了可选链运算符,代码如下
var price = result?.body?.data?.price;可选运算符不仅能作用到属性上,也能作用到方法。
const result = {}; const price = result?.body?.data?.price; const user = {}; const name = user?.getInfo?.().getName?.(); const respone = {}; const firstProduct = respone?.body?.data?.products?.[0]; -
空值合并运算符 - Nullish coalesceing oprator
获取对象的属性的时候,我们经常需要为 null/undefined 的属性设置默认值。目前正常的情况下我们可以使用 || 运算符,例如:
var user = {}; var name = user.name || 'p9';但是,这么做会导致false,0,空字符串等属性会被覆盖掉,这是我们不愿意看到的,这时候就可以使用空值合并运算符来避免。例如:
const response = { settings: { nullValue: null, height: 400, animationDuration: 0, headerText: '', showSplashScreen: false } }; const undefinedValue = response.settings.undefinedValue ?? 'some other default'; // result: 'some other default' const nullValue = response.settings.nullValue ?? 'some other default'; // result: 'some other default' const headerText = response.settings.headerText ?? 'Hello, world!'; // result: '' const animationDuration = response.settings.animationDuration ?? 300; // result: 0 const showSplashScreen = response.settings.showSplashScreen ?? true; // result: false标准化的全局对象 - globalThis -
动态引入 import()
如果您有一个写满实用程序功能的文件,而且其中某些功能可能很少使用,那么导入其所有依赖项可能只是浪费资源。 现在,我们可以使用
async / await在需要时动态导入依赖项。(async () => { if (process.env.NODE_ENV === 'development') { // 动态加载Vconsole const { default: VConsole } = await import('vconsole'); new VConsole(); } })() -
BigInt
avaScript可以处理的最大安全整数是
(2^53 - 1),我们可以在MAX_SAFE_INTEGER中看到const max = Number.MAX_SAFE_INTEGER; console.log(max); // 9007199254740991超过这个数字就会变得有点奇怪…
console.log(max + 1); // 9007199254740992 console.log(max + 2); // 9007199254740992 console.log(max + 3); // 9007199254740994 console.log(Math.pow(2, 53) == Math.pow(2, 53) + 1); // true我们可以使用新的
BigInt数据类型来解决这个问题。通过把字母n放在末尾,我们可以与大得离谱的数字进行交互。我们无法将标准数字与BigInt数字混合在一起,因此任何数学运算都需要使用BigInt来完成。const bigNum = 100000000000000000000000000000n; console.log(bigNum * 2n); // 200000000000000000000000000000n -
Promise.allSettled
当我们处理多个Promise时,特别是当它们相互依赖时,记录每个Promise所发生的事情来调试错误是很有必要的。通过
Promise.allSettled,我们可以创建一个新的Promise,它只在所有传递给它的Promise都完成时返回一个数组,其中包含每个Promise的数据。const p1 = new Promise((res, rej) => setTimeout(res, 1000)); const p2 = new Promise((res, rej) => setTimeout(rej, 1000)); Promise.allSettled([p1, p2]).then(data => console.log(data)); // [ // Object { status: "fulfilled", value: undefined}, // Object { status: "rejected", reason: undefined} // ] -
私有属性
类的主要目的之一是将代码包含到更可重用的模块中。因为你将创建一个在许多不同地方使用的类,所以你可能不希望它内部的所有内容都是全局可用的。现在,通过在属性或方法前面添加一个简单的哈希符号,我们可以将它们完全保留为类内部使用.
class Message { #message = "Howdy" // 相当于ts里的 private greet() { console.log(this.#message) } } const greeting = new Message() greeting.greet() // Howdy console.log(greeting.#message) // Private name #message is not defined