ES2020 已定稿!赶忙上手实践一下吧(真实场景例子)

译原文:blog.bitsrc.io/es2020-has-…
做者:Mahdhi Rezvi
译:图雀社区javascript

近年来,JavaScript 的发展很是迅速。 尤为是在2015 年 ES6 发布以后,状况变得更好。前端

如今 许多新的特性被提议包括在 ES2020版本中。好消息是这些已经已经敲定。 如今,咱们得到了最终定稿的功能清单,它们将在被批准发布以后出如今备受期待的 ES2020 中。 其中一些功能使我很是兴奋,由于在它们存在以前编写代码时遇到将会遇到不少麻烦。 让咱们看看它们是什么吧!java


可选链操做符(Optional Chaining Operator)

对我我的来讲,这是 ES2020最使人兴奋的特色之一。 我已经编写了不少程序,这些程序将会从这个新特性中获益匪浅。git

可选链操做符容许您安全地访问对象的深嵌套属性,而没必要检查每一个属性是否存在。 让咱们看看这个特性对咱们有什么帮助。正则表达式

拥有可选链操做符以前

const user = {
  firstName: "Joseph",
  lastName: "Kuruvilla",
  age: 38,
  address: {
    number: "239",
    street: "Ludwig Lane",
    city: "Chennai",
    zip: "600028",
    prop1: {
      prop2: {
        prop3: {
          prop4: {
            value: "sample",
          },
        },
      },
    },
  },
};

if (user && user.address) {
  console.log(user.address.zip);
  //600028
}

if (
  user &&
  user.address &&
  user.address.prop1 &&
  user.address.prop1.prop2 &&
  user.address.prop1.prop2.prop3 &&
  user.address.prop1.prop2.prop3.prop4
) {
  console.log(user.address.prop1.prop2.prop3.prop4.value);
  //sample
}

//Accessing unexisting property
console.log(user.address.prop102.po);
//Error
复制代码

正如您在上面看到的,您必须检查每一个级别中是否存在该属性,以免出现没法读取未定义属性“ po”的错误。 随着嵌套级别的增长,手动检查的属性数量也会增长。 这意味着咱们必须检查每一个级别,以确保它不会在遇到未定义或空对象时崩溃。浏览器

拥有可选链式操做符以后

随着可选链式操做符 (Optional Chaining) 的引入,咱们前端的工做变得容易多了。 经过简单地使用可选链式操做符  ?.  咱们能够访问深嵌套的对象,而没必要检查未定义或空对象。安全

让咱们看看它是如何运做的。app

const user = {
  firstName: "Joseph",
  lastName: "Kuruvilla",
  age: 38,
  address: {
    number: "239",
    street: "Ludwig Lane",
    city: "Chennai",
    zip: "600028",
    prop1: {
      prop2: {
        prop3: {
          prop4: {
            value: "sample",
          },
        },
      },
    },
  },
};

console.log(user?.address?.zip);
// 600028

console.log(user?.address?.prop1?.prop2?.prop3?.prop4?.value);
// sample

//Accessing unexisting property
console.log(user?.address?.prop102?.po);
//undefined
复制代码

太神奇了! ES2020 成功地经过引入一个单独的代码操做符  ?. 来减小了如此多的代码行数!ide


空值合并操做符(Nullish coalescing operator)

这是另外一个令我兴奋的功能,当我第一次在 proposal stage, 了解到的时候,我由衷的喜欢这个特性,由于我已经历了编写单独的函数来手动检查这个特性的麻烦。函数

空值合并操做符容许您检查  nullish  值而不是  falsey  值。 Nullish 值是指  nullundefined 的值。 而 falsey 值是诸如空字符串、数字0、  undefined 、  null 、  false 、  NaN  等等的值。 这对你来讲可能听起来没什么不一样,可是在现实中,这意味着不少。

让咱们看看这是怎么回事。

在有空值合并操做符以前

我最近作了一个项目,我须要容许黑暗模式(Dark Mode)切换功能。 我必须检查输入是  true 仍是  false 。 若是用户没有设置任何值,则默认为  true 。 下面就是我如何在有空值合并操做符以前实现它的:

const darkModePreference1 = true;
const darkModePreference2 = false;
const darkModePreference3 = undefined;
const darkModePreference4 = null;
const getUserDarkModePreference = (darkModePreference) => {
  if (darkModePreference || darkModePreference === false) {
    return darkModePreference;
  }
  return true;
};
getUserDarkModePreference(darkModePreference1);
// true
getUserDarkModePreference(darkModePreference2);
// false
getUserDarkModePreference(darkModePreference3);
// true
getUserDarkModePreference(darkModePreference4);
// true
复制代码

在有空值合并操做符以后

在有空值合并操做符以后,您所要作的就是使用  ??  操做符。不须要  if  语句:

const darkModePreference1 = true;
const darkModePreference2 = false;
const darkModePreference3 = undefined;
const darkModePreference4 = null;
const getUserDarkModePreference = (darkModePreference) => {
  return darkModePreference ?? true;
};
getUserDarkModePreference(darkModePreference1);
// true
getUserDarkModePreference(darkModePreference2);
// false
getUserDarkModePreference(darkModePreference3);
// true
getUserDarkModePreference(darkModePreference4);
// true
复制代码

这里基本上发生的状况是,若是变量 darkModePreference 包含一个  nullish  值,那么将值 true 赋给它。 简单,简短,易于理解。


动态 import(Dynamic Imports)

这个特性将帮助您的应用程序更加高效的执行, 动态 import 容许您将 JS 文件做为原生应用用程序中的模块动态导入。 在 ES2020以前,不论是否使用模块,都应该导入模块。

例如,假设咱们须要添加一个功能来下载 pdf 格式的文件。

让咱们看看如何在 动态 import 以前和以后实现这一点。

在 动态 import  以前

实际上,不会全部的页面访问者使用下载 pdf 的选项。 可是,不管咱们的访客是否使用它,它仍然须要被导入。 这意味着这个 pdf 模块也能够在页面加载期间被下载。

import { exportAsPdf } from "./export-as-pdf.js";
const exportPdfButton = document.querySelector(".exportPdfBtn");
exportPdfButton.addEventListener("click", exportAsPdf);
复制代码

这种开销能够经过使用延迟加载模块(lazy loaded modules)来减小。 能够经过称为代码分割 (code-splitting)的方法来实现,这在 Webpack 或其余模块打包工具已经可使用了。 可是对于 ES2020,咱们能够直接使用它了,而不须要模块打包工具,如 Webpack。

在动态导入(动态 import)以后

const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', () => {
  import('./export-as-pdf.js')
    .then(module => {
      module.exportAsPdf()
    })
    .catch(err => {
      // handle the error if the module fails to load
    })
})
复制代码

正如您在上面的代码中看到的,如今只有在须要模块时才延迟加载模块。 从而减小开销和页面加载时间。


Promise.allSettled

若是你有一个场景,在全部 Promise 都完成以后必须执行一个任务,那么你可能使用  Promise.all() 方法。 可是这个方法有一个缺点。 当你的任何一个 Promise 被 Rejected 时,Promise 方法就会抛出一个错误。 这意味着您的代码不会等到全部的 Promise 都完成。

这可能不是你想要的。 若是你想要这样的东西: “我不在意他们的结果。 只需所有运行” ,那么你可使用新的  Promise.allSettled() 方法。 这种方法只有在你的全部 Promise 都  settled ーー 要么  Resolved ,要么  Rejected ーー 时才会  Resolved

在拥有 Promise.allSettled 以前

const PromiseArray = [
  Promise.resolve(100),
  Promise.reject(null),
  Promise.resolve("Data release"),
  Promise.reject(new Error("Something went wrong")),
];
Promise.all(PromiseArray)
  .then((data) =>
    console.log("all resolved! here are the resolve values:", data)
  )
  .catch((err) => console.log("got rejected! reason:", err));
//got rejected! reason: null
复制代码

如上所述,当其中一个 Promise 被  rejected 时, Promise 就会抛出错误。

在拥有 Promise.allSettled 以后

const PromiseArray = [
  Promise.resolve(100),
  Promise.reject(null),
  Promise.resolve("Data release"),
  Promise.reject(new Error("Something went wrong")),
];
Promise.allSettled(PromiseArray)
  .then((res) => {
    console.log(res);
  })
  .catch((err) => console.log(err));
//[
// {status: "fulfilled", value: 100},
// {status: "rejected", reason: null},
// {status: "fulfilled", value: "Data release"},
// {status: "rejected", reason: Error: Something went wrong ...}
//]
复制代码

尽管有些 Promise 被 rejected 了,Promise.allSettled 返回了全部的 Promise 的结果。

globalThis

globalThis  包含对全局对象的引用,与环境无关。 在浏览器中,全局对象是  window 对象。 在 Node 环境中,全局对象是   global 或者 Web workers 中的  self

在拥有 globalThis 以前

咱们在工做中会有须要编写一份同时运行在 Node 和浏览器中的通用代码,当咱们要取得全局对象时,一般须要作不少工做和逻辑判断:

beforeGlobalThis = (typeof window !== "undefined"
? window
: (typeof process === 'object' &&
   typeof require === 'function' &&
   typeof global === 'object')
    ? global
    : this);

beforeGlobalThis.tuture = '小若燕雀,亦可一展宏图';
复制代码

在拥有 globalThis 以后

咱们能够直接使用 globalThis 去引用全局对象,而不用去担忧环境的问题:

globalThis.tuture = '小若燕雀,亦可一展宏图';
复制代码

上面的代码在浏览器或者 Node 环境中都是通用的,你能够放心使用!


BigInt

容许您使用大于 Javascript 中容许的最大值的数字。 这个数字是  pow(2,53)-1 。 尽管这不能向后兼容,由于传统的数字系统(IEEE 754)不能支持这种大小的数字。

String.matchall

matchAll() 是一个与正则表达式相关的方法。 此方法返回与正则表达式匹配的字符串的全部结果的迭代器,包括捕获组。 这个方法已经被添加到 String 原型中。


ES2020 中那个特性最让你兴奋?欢迎在评论中发表你的见解!✌️

Happy Coding!

参考资源

想要学习更多精彩的实战技术教程?来图雀社区逛逛吧。

相关文章
相关标签/搜索