ECMAScript 2020 是我们最喜欢的编程语言的第 11 版,其中包含一些新功能。有些是小特性,但有些将会有可能永远改变我们编写 JavaScript 的方式。
ES2015 引入了 static import 语法。现在你可以从一个模块导出变量,然后将其导入另一个模块。
// utils.js
export function splitName(name) {
return name.split(" ");
}
// index.js
import { splitName } from "./utils";
console.log(splitName("John Snow"));
这种语法被称为静态语法,因为你无法在运行时动态导入模块(取决于某些条件)。请注意,这不一定是坏事:可以在编译时优化静态导入,并允许 Tree Shaking。
另一方面,如果合理地使用了动态导入,则可以通过按需加载依赖项来帮助减少分发包的大小。
新的 dynamic import 语法看起来像一个函数(但不是),它返回 promise,这也意味着可以将其与 async/await一起使用。
// ...
const mod = figure.kind === "rectangle" ? "rectangle.js" : "circle.js";
const { calcSquare } = await import(mod);
console.log(calcSquare(figure));
流行的用 short-circuting 设置默认值的方法有其缺陷。由于它实际上不是在检查空值,而是在检查是否为假,因此它会以诸如 false 或 0(两者均被视为假)。
ES2020引入了一个新的运算符 ??,该运算符的工作原理与其类似,但仅在初始值为 null 或 undefined 时才赋值为右手。
这是一个简单的例子:
const initialVal = 0;
// old way
const myVar = initialVal || 10; // => 10
// new way
const myVar = initialVal ?? 10; // => 0
新的 optional chaining 运算符用来在处理嵌套对象并检查可能的 undefineds 时使代码更短。
const user = { name: "John" };
// Fails with `Uncaught TypeError: Cannot read property 'city' of undefined`
const city = user.address.city;
// Works but verbose
let city = "Not Set";
if (user.address !== undefined && user.address !== null) {
city = user.address.city;
}
// Works and concise but requires a 3rd party library
const city = _.get(user, "address.city", "Not Set");
const city = user?.address?.city ?? "Not Set";
BigInt 是一个新对象,代表的数字大于Number.MAX_SAFE_INTEGER(即2 ^ 53-1)。对于普通人来说,这听起来可能绰绰有余,但对于某些数学应用程序和机器学习而言,新的 BigInt 类型就能够派上用场了。
它带有自己的字面量表示法(只需在数字末尾添加 n):
const x = 9007199254740991n;
// or it can be constructed from a string
const y = BigInt("9007199254740991234");
BigInts 带有自己的代数方法,它不能转换为常规数字,因此我们不能把 number 与 BigInt 混淆。应该先将它们强制转换为任一类型。
1 === 1n; // => false
1n + 1; // throws Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
6n << 3; // nope
6n << 3n; // that works
所以这是一个例子。想象一下,你有一个很长的文本字符串,并且需要从中提取所有标签(即以 # 开头的单词)。用正则表达式可以解决!
const tweet = "#JavaScript is full of #surprises. Both good and bad ones #TIL";
for (h of tweet.matchAll(/(#\w+)/g)) {
console.log(h[0]);
}
// or
const tags = [...tweet.matchAll(/(#\w+)/g)]
matchAll 返回一个迭代器。我们可以用 for..of 对其进行迭代,也可以将其转换为数组。
还记得 Promise.all 函数吗?它仅在所有的 Promise 均得到解决时才会被解决。假如其中有一项 Promise 被拒绝,此时可能还有其他 promise 没完成。
新的 allSettled 的行为有所不同。只有当所有的 promise 全部都完成时(即成功或被拒绝),它才会被解决。它被分解为一个数组,其中包含 promise 的状态及其所解决的内容(或错误)。
因此, allSettled 永远不会被拒绝。它要么是 pending,要么是 resolved。
一个现实中的问题是删除加载指示器:
// const urls = [...]
try {
await Promise.all(urls.map(fetch))
} catch (e) {
// at least one fetch is rejected here, but there may others still pending
// so it may be too early for removing the loading indicator
removeLoading()
}
// with allSettled
await Promise.allSettled(urls.map(fetch))
removeLoading()
在 JavaScript 中,总是有一个包含所有内容的大型上下文对象。传统上,在浏览器中是 window。但是,如果尝试在 Node 程序中访问它,则会收到错误消息。 Node 中没有 window 全局对象;而是有一个 window 对象。另外在 WebWorker 中,没有访问 window 的权限,但是有 self 的权限。
新的 globalThis 属性可以消除差异。这意味着你可以自始至终去引用 globalThis,而无需关心你现在所处的上下文是什么。
如果你认为这命名有点尴尬,那么我完全同意你的看法,但是请注意,将其命名为 self 或 global 可能会使某些旧代码不兼容。所以我想我们必须忍受这一点。
为了方便你的学习,这里是本文提到的每个功能的 MDN 文档的链接。
JavaScript 用“共享一切”的方法加载代码,这是该语言中最容易出错且最容易让人感到困惑的地方。其他语言使用诸如包这样的概念来定义代码作用域,但在 ECMAScript 6 以前,在应用程序的每一个 JavaScript 中定义的一切都共享一个全局作用域
回调地域 既一个异步请求需要另一个异步请求结果;由于 Javascript 是单线程的,所以这里执行顺序是 ajax1 -> ajax2 -> ajax3 -> ajax4;但是又由于这四个是异步操作
ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会)通过ECMA-262标准化的脚本程序设计语言,一种可以在宿主环境中执行计算并能操作可计算对象的基于对象的程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript
函数声明 与 函数表达式 是有区别的。执行代码时,解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。
ECMAScript 2020 是 ECMAScript 语言规范的第11版。自1997年出版第一版以来,ECMAScript 已发展成为世界上使用最广泛的通用编程语言之一。
ECMAScript 语言规范每年都会进行一次更新,而备受期待的 ECMAScript 2024 将于 2024 年 6 月正式亮相。目前,ECMAScript 2024 的候选版本已经发布,为我们带来了一系列实用的新功能。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!