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


Posted in Javascript onMay 25, 2020

近年来,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 已定稿内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript URL编码和解码使用说明
Apr 12 Javascript
js特殊字符转义介绍
Nov 05 Javascript
查找Oracle高消耗语句的方法
Mar 22 Javascript
Node.js中使用Log.io在浏览器中实时监控日志(等同tail -f命令)
Sep 17 Javascript
Jquery 实现弹出层插件
Jan 28 Javascript
超全面的javascript中变量命名规则
Feb 09 Javascript
基于Vue实例生命周期(全面解析)
Aug 16 Javascript
使用vue + less 实现简单换肤功能的示例
Feb 21 Javascript
vue-awesome-swiper 基于vue实现h5滑动翻页效果【推荐】
Nov 08 Javascript
elementUI select组件使用及注意事项详解
May 29 Javascript
vue 解决uglifyjs-webpack-plugin打包出现报错的问题
Aug 04 Javascript
vue-cropper插件实现图片截取上传组件封装
May 27 Vue.js
Javascript原型链及instanceof原理详解
May 25 #Javascript
Node登录权限验证token验证实现的方法示例
May 25 #Javascript
详解Node.js使用token进行认证的简单示例
May 25 #Javascript
基于redis的小程序登录实现方法流程分析
May 25 #Javascript
JSONP解决JS跨域问题的实现
May 25 #Javascript
JS实现时间校验的代码
May 25 #Javascript
使用Typescript和ES模块发布Node模块的方法
May 25 #Javascript
You might like
PHP中array_merge和array相加的区别分析
2013/06/17 PHP
PHP+redis实现的悲观锁机制示例
2018/06/12 PHP
php的优点总结 php有哪些优点
2019/07/19 PHP
设定php简写功能的方法
2019/11/28 PHP
js特殊字符过滤的示例代码
2014/03/05 Javascript
为什么Node.js会这么火呢?Node.js流行的原因
2014/12/01 Javascript
JavaScript实现带播放列表的音乐播放器实例分享
2016/03/07 Javascript
简述Matlab中size()函数的用法
2016/03/20 Javascript
jquery自动补齐功能插件flexselect用法示例
2016/08/06 Javascript
Angular中ng-bind和ng-model的区别实例详解
2017/04/10 Javascript
vue-quill-editor+plupload富文本编辑器实例详解
2018/10/19 Javascript
vue+django实现一对一聊天功能的实例代码
2019/07/17 Javascript
layer弹出层自定义提交取消按钮的例子
2019/09/10 Javascript
微信小程序实现上拉加载功能示例【加载更多数据/触底加载/点击加载更多数据】
2020/05/29 Javascript
JavaScript类的继承多种实现方法
2020/05/30 Javascript
SpringBoot+Vue 前后端合并部署的配置方法
2020/12/30 Vue.js
[01:00]一分钟回顾2018DOTA2亚洲邀请赛现场活动
2018/04/07 DOTA
[00:59]DOTA2英雄背景故事——上古巨神
2020/06/28 DOTA
Python BeautifulSoup中文乱码问题的2种解决方法
2014/04/22 Python
Python使用Pycrypto库进行RSA加密的方法详解
2016/06/06 Python
解决pycharm运行出错,代码正确结果不显示的问题
2018/11/30 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
Python3.9又更新了:dict内置新功能
2020/02/28 Python
Python ini文件常用操作方法解析
2020/04/26 Python
Django设置Postgresql的操作
2020/05/14 Python
土耳其时尚潮流在线购物网站:Trendyol
2017/10/10 全球购物
Kiwi.com中国:找到特价机票并发现新目的地
2019/10/27 全球购物
局部内部类是否可以访问非final变量?
2013/04/20 面试题
大学生找工作推荐信范文
2013/11/28 职场文书
《登鹳雀楼》教学反思
2014/04/09 职场文书
挂靠协议书范本
2014/04/22 职场文书
国际经济贸易专业自荐信
2014/06/13 职场文书
社区党建工作汇报材料
2014/08/14 职场文书
党员贯彻十八大精神思想汇报范文
2014/10/25 职场文书
2014法制宣传日活动总结范文
2014/11/01 职场文书
python实现简单区块链结构
2021/04/25 Python