ES2020的这些新功能令人期待
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。
原文出处:https://blog.bitsrc.io/es2020-has-been-finalized-here-is-what-im-excited-about-414959bc2f7f
最近这几年,随着JavaScript及前端领域的持续迅猛发展,尤其是在2015年ES6发布后,这个发展的进程也变得越来越快起来。许多新功能也将计划包含在ES2020版本中。
前段时间,我们得到了关于ES2020已经基本定稿的功能列表,这个功能列表可以说大部分都会出现在ES2020新版本发布列表中。而在这其中的部分功能我认为将备受期待,因为作为一个开发者,在这些功能违背发布之前,在编码时遇到一些难题需要我们自己去解决。那么,让我们看看这些功能都是什么吧。
可选链接
就我个人而言,我认为这是ES2020最令人期待的功能之一,这个功能使你可以安全地访问对象的深层嵌套属性,而不必检查每个属性是否存在。那么,Talk is cheap. Show me the code,让我们看看实际在代码层面有什么改变吧。
在使用可选链接之前的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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); } //访问不存在的属性 console.log(user.address.prop102.po); //Error |
如上所示,在访问属性前,你必须检查所访问层级中的属性是否存在,以防止出现Cannot read property 'po' of undefined错误。而随着嵌套级别的增加,你手动检查的属性数量也将随之增加。这意味着一旦我们漏过一项,将会在程序中引发undefined或null对象错误,导致应用出现问题。
可选链接功能出现后
而随着可选链接功能的出现,我们的工作将会变得比较轻松,通过使用可选链接运算符“?.”我们可以访问深度嵌套的对象,而不必检查其是否未定义或null对象。
让我们看看它是如何使用的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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)
当我第一次听说这个功能时,我认为这是另一个令人值得期待的功能,因为我就曾因为在大量重复手动实现该功能时,非常期待有类似这个功能的出现。
空值合并可以让你检查nullish值而不是falsey值。nullish值是指null或undefined,falsey值是指空字符串,数字0, undefined,null,false,NaN,等值。虽然看起来好像这两个值没什么区别,但实际上差异却很大。
在空值合并之前
我最近在做一个项目,其中需要增加暗夜模式的切换功能。我必须检查输入是否为 true或者false。如果用户没有设置任何值,默认它应该为true。下面是我如何在空值合并出现前实现它的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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包含一个空值,那么就把true赋给它,使用这个特性的代码简单易懂。
动态导入
此功能将帮助你的应用更高效地运行。动态导入允许你实时地在应用中以模块的形式按需导入JS文件。在ES2020之前,无论你是否使用了该模块,都应该提前导入它。
例如,假设我们需要添加一个功能来下载一个pdf格式的文件。
让我们看看如何在动态导入之前和之后如何实现这一点有什么异同。
动态导入之前
在实际项目中,下载pdf的功能不会被所有的网站访客使用。但是,不管我们的访问者是否使用它,它都需要导入。这意味着这个pdf模块也会在页面加载时被载入。
1 2 3 4 | import { exportAsPdf } from './export-as-pdf.js' const exportPdfButton = document.querySelector( '.exportPdfBtn' ); exportPdfButton.addEventListener( 'click' , exportAsPdf); |
这种开销可以通过使用延迟加载模块来减少。可以通过代码分离(code-splitting)来实现,代码分离已经可以通过webpack或其他模块打包工具来实现。
但是在ES2020中我们以原生的方式来实现这个功能,不再需要模块打包工具等其他方式减少开销了。
动态导入之后
1 2 3 4 5 6 7 8 9 10 11 | 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被拒绝时,都会抛出一个错误。这意味着你的代码不会等到你所有的promise都完成。
这可能不是你想要的。如果你的需求是不关心它们的结果,只需将它们全部运行,你可以使用新的Promise.allSettled()方法。这种方法只有在你所有的promise都执行完成之后才会调用。
使用 promise.all
1 2 3 4 5 6 7 8 9 10 11 | 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失败时,会引发错误。
使用 promise.allSettled
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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被拒绝,Promise.allSettled仍然会在所有promise执行完成后为你返回结果。
其他也很令人期待的功能
BigInt
允许你使用比Javascript中允许的最大值大的数字。这个数字是pow(2,53)-1。不过这并不是向后兼容的,因为传统的浮点数标准(IEEE 754)不支持这种大小的数字。
String.matchAll
matchAll() 是一个和正则表达式相关的方法。它返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。这个方法添加到了 String 原型里。
globalThis
globalThis是对全局对象的引用,与环境无关。在浏览器中,全局对象是window对象。在Node环境中,全局对象是global对象,在web worker中是self。
总结
本文中有些功能是我以个人角度总结梳理的,如果缺少了哪个功能或有我理解有误的地方,欢迎大家在评论中指出,谢谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2017-07-10 多维透视表 - 矩表实现商品销售对比统计