这几个例子让你了解ES10 (ES2019)的8个新特性

235 阅读6分钟

介绍

虽然JavaScript被许多人讨厌,也被许多人喜爱, 但事实上JavaScript是Web 开发的标准之一。最近,它在开发基于 Web 的应用程序方面一直处于垄断地位(由于 WebAssembly 或 WASM 不再是这种情况),并且这种情况已经有一段时间了。在本文中,我将介绍在 ES10 或 ES2019引入的 8 个新特性。

下面是我们将要介绍的8个ES新特性:

  • Optional Catch Binding
  • Object.fromEntries
  • Array.flat
  • Array.flatMap
  • String#{trimStart,trimEnd}
  • Dynamic Import (at the time of writing this article, the proposal was in stage 3 - see here)
  • globalThis object (at the time of writing this article, the proposal was in stage 4 - see here)

请注意,在 ES10 中还引入了另外几个。本文仅涵盖我认为在实践中最有用的那些。如果您有什么要补充的,请随时发表评论

1. Optional Catch Binding

在这成为可能之前,我们作为开发人员被迫在使用语句时绑定异常try...catch。引擎并不关心这个异常后来是否被使用,这是一件很不方便的事情。

更新前:

try {
  // some code
  return true;
} catch(unusedException) { // here is the problem
  return false;
}

更新后 (新的 ES10 特性):

try {
  // some code
  return true;
} catch {
  return false;
}

如上所示,如果我们不需要异常绑定,我们现在可以省略它。这是一种进步。通过这种方式,我们的代码对于***下一个继任者(一个将在未来某个时候继续我们的工作的人)来说更清晰,更少混淆。

2. Object.fromEntries()

从方法名称上看可能不是那么清楚,但是该Object.fromEntries方法将键值对列表转换为对象。您可以将映射或数组转换为对象。而Object.entries,是将给定的对象转换为其键值对表示。

想象一下,您有一个包含用户名和年龄作为单独项目的用户列表。您可以使用Object.fromEntries将该列表转换为对象。

const users = [['John', 49], ['Frank', 25], ['David', 36]];
const usersAge = Object.fromEntries(users);
console.log(usersAge);

// outputs: {John: 49, Frank: 25, David: 36}

3. Array.flat()

此方法创建一个新数组,其中所有子数组元素以递归方式连接到指定深度,这意味着在我们有数组的情况下,我们可以获得单个数组作为结果。并非源数组的每一项都需要是数组。Array.flat足够灵活来解决这个问题。默认深度为 1。

我们通过邮政编码和城市之间的联系来进行说明。比如,如果两个城市位于不同的州,则相同的邮政编码可以引用它们(如果我没记错的话)。并且您的应用程序可能需要所有城市的列表,而不管其邮政编码如何,因此它最终可能会得到一个类似于以下内容的列表:

['City 1', ['City 2'], ['City 3', 'City 4']]

为了使这个列表更易于使用和迭代,我们可以使用方法将其展平Array.flat

const cities = ['City 1', ['City 2'], ['City 3', 'City 4']];
console.log(cities.flat()); // outputs ["City 1", "City 2", "City 3", "City 4"]

为了使这个列表更易于使用和迭代,我们可以使用方法将其展平Array.flat

const numbers = [1, 2, [3, 4],, 5, 6,, [7,8]];
console.log(numbers.flat()); // outputs [1, 2, 3, 4, 5, 6, 7, 8]

4. Array.flatMap()

此方法首先使用映射函数对,每个函数进行映射,然后将结果放到一个新数组中。

对于这个例子,我们可以修改上面例子中的users列表Object.fromEntries

想象一下,除了姓名和年龄之外,我们还会收到列表中每个项目中的用户关注者。Object.fromEntries在这种情况下无法帮助我们,因为它会简单地忽略第三个元素,因为它仅适用于键值对,这意味着每个元素的最大项目数为 2。

相反,我们应该利用Array.flatMap来实现各项杂交的结果。在我看来,这个结果要好一些,因为它会提供更多的上下文。

const users = [['John', 49, 96], ['Frank', 25, 388], ['David', 36, 14]];
const usersFlattened = users.flatMap(([name, age, followers]) => {
    return { name, age, followers };
});
console.log(usersFlattened);

// outputs:
// 0: {name: "John", age: 49, followers: 96}
// 1: {name: "Frank", age: 25, followers: 388}
// 2: {name: "David", age: 36, followers: 14}
//   length: 3

5-6. String.trimStart() & String.trimEnd()

String.trimStart方法从字符串的开头删除空格,String.trimEnd方法从字符串的末尾删除空格。它们都有一个别名,trimLefttrimRight

const message = '   Hello ES10   ';

console.log(message.trimStart()); // outputs 'Hello ES10   '
console.log(message.trimEnd()); // outputs '   Hello ES10'
console.log(message); // outputs '   Hello ES10   '

请注意,这两种方法都将返回一个去除了空格的新字符串。而原始字符串保持不变。

7. Dynamic Import

通过动态导入模块,我们收到了对所请求模块的模块命名空间对象(导出)的承诺。我们也可以使用 async/await 将导入分配给变量。

因此我们导入模块的方式将会是如下所示:

// Default export
export default () => {
  console.log('Do default');
};

// Named export
export const doSomething = () => {
  console.log('Do something');
};

现在可以通过以下方式之一动态导入它:

import('..my-path/my-module.js').then((module) => {
  module.default();
  module.doSomething();
  // ...
});

或者

(async () => {
  const module = await import('..my-path/my-module.js')
  module.default();
  module.doSomething();
  // ...
})();

8. globalThis Object

globalThis标准化之前,我们有几种方法来确定我们的应用程序所在环境的全局对象。第一种方法是使用Function这样的:

const global = Function('return this')();

例如,在浏览器中,这将返回Window对象。但是,给定的方法会导致 CSP 违规,以这种方式拒绝Function使用,因此我们必须使用手动检查来确定全局对象,如下所示:

const 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');
}

const global = getGlobal(); // will return window object in the browser

// array usage example
const numbers = new global.Array(1, 2, 3);
console.log(numbers); // outputs [1, 2, 3];

通常,库构建者使用这种方法并使用为库提供正确全局对象的即时函数包装他们的代码。如下所示:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
      (global = global || self, global.myLib = factory());
}(this, function () {
    // the code

  return {} // return the lib namespace
}));

如今,这是由 rollup.js 或 webpack 等打包工具自动完成的

有了globalThis,这将不再需要,全局对象将为我们标准化。

结论

JavaScript 得到了很多改进,这是肯定的。其中一些比其他的更有用,但总的来说,它们使我们的生活更轻松,使我们能够编写干净且可维护的代码。我很高兴看到未来会怎样!

和往常一样,感谢您的阅读,我们下一篇文章再见。