ES2020 已定稿,真实场景案例分析

 更新时间:2020年05月25日 11:10:33   作者:图雀社区  
许多新的特性被提议包括在 ES2020版本中。好消息是这些已经已经敲定。 现在,我们获得了最终定稿的功能清单,它们将在被批准发布之后出现在备受期待的 ES2020 中,具体内容详情,大家可以阅读下本文

近年来,JavaScript 的发展非常迅速。 尤其是在2015 年 ES6 发布之后,情况变得更好。

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

可选链操作符(Optional Chaining Operator)

对我个人来说,这是 ES2020最令人兴奋的特点之一。 我已经编写了很多程序,这些程序将会从这个新特性中获益匪浅。

可选链操作符允许您安全地访问对象的深嵌套属性,而不必检查每个属性是否存在。 让我们看看这个特性对我们有什么帮助。

拥有可选链操作符之前

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) 的引入,我们前端的工作变得容易多了。 通过简单地使用可选链式操作符?.我们可以访问深嵌套的对象,而不必检查未定义或空对象。

让我们看看它是如何运作的。

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 成功地通过引入一个单独的代码操作符?.来减少了如此多的代码行数!

空值合并操作符(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 原型中。

参考资源

ECMA
InfoQ
Article by Tyler Hawkins

总结

到此这篇关于ES2020 已定稿,真实场景案例分析的文章就介绍到这了,更多相关ES2020 已定稿内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS实现上传文件显示进度条

    JS实现上传文件显示进度条

    这篇文章主要为大家详细介绍了JS实现上传文件显示进度条,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • js 多层叠的TAB选项卡

    js 多层叠的TAB选项卡

    一个多层叠的TAB选项卡,自适应宽度(自行更改nonstop的width测试效果)。
    2010-01-01
  • JS前端首屏优化技巧

    JS前端首屏优化技巧

    这篇文章主要为大家介绍了JS前端首屏优化技巧,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • javascript实现信息增删改查的方法

    javascript实现信息增删改查的方法

    这篇文章主要介绍了javascript实现信息增删改查的方法,实例分析了javascript操作页面元素实现针对页面信息的增删改查功能,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • 微信小程序 rich-text的使用方法

    微信小程序 rich-text的使用方法

    这篇文章主要介绍了 微信小程序 rich-text的使用方法的相关资料,这里提供属性及方法并实现实例,帮助大家学习理解,需要的朋友可以参考下
    2017-08-08
  • JS实现的自动打字效果示例

    JS实现的自动打字效果示例

    这篇文章主要介绍了JS实现的自动打字效果,涉及javascript递归算法、字符串操作及事件函数相关使用技巧,需要的朋友可以参考下
    2017-03-03
  • JS多物体实现缓冲运动效果示例

    JS多物体实现缓冲运动效果示例

    这篇文章主要介绍了JS多物体实现缓冲运动效果的方法,涉及javascript基于时间函数进行动态运算实现页面元素动态操作的相关技巧,需要的朋友可以参考下
    2016-12-12
  • TypeScript类型使用示例剖析

    TypeScript类型使用示例剖析

    这篇文章主要为大家介绍了TypeScript类型使用示例剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • 微信小程序实现image组件图片自适应宽度比例显示的方法

    微信小程序实现image组件图片自适应宽度比例显示的方法

    这篇文章主要介绍了微信小程序实现image组件图片自适应宽度比例显示的方法,简单讲述了image组件的常用属性,并结合实例形式分析了微信小程序实现图片自适应宽度比例的相关操作技巧,需要的朋友可以参考下
    2018-01-01
  • 微信小程序自定义tabBar的步骤记录

    微信小程序自定义tabBar的步骤记录

    微信小程序开发越来越多样化,各种丰富的设计及体验,自定义tabBar也经常使用,下面这篇文章主要给大家介绍了关于微信小程序如何自定义tabBar的相关资料,需要的朋友可以参考下
    2021-08-08

最新评论