ES11(ES2020)已经release了,抽个时间来总结一下它的新特性。
1.私有变量
ES11在类中新增私有变量控制符#,在内部变量或者函数前添加一个hash符号#,可以将它们设置为私有属性,只能在类的内部可以使用。
这时我想要获取私有变量的值或者设置私有变量的值该怎么办,很简单,根据我类中定义的特殊的方法就可以实现,比如:
暂时私有变量(属性),就说到这里,可能以后会发现更多的sao操作再分享。
2.空值合并运算符
首先说一下空值合并运算符解决的是什么问题,在日常开发中,取对象属性的时候,如果对象中没有这个属性,我们获取的时候会获取到一个undefined的默认值
但是我们并不想获取到undefined这个默认值,我们需要的是我们自己给定的默认值,有人会说在定义对象的时候定义一个默认值就好了,但是如果是接口返回的数据对象中没有这个字段时,我们通常是用一个中间变量转存整理,这样就会显得比较麻烦,并且效率不高。ES11中就新增了一个空值合并操作符,来进行自定义个默认值。
空值合并操作符就是??,这个意思就是如果左侧的值为null或者undefined就返回左侧的值,如果没有就返回右侧的值,那么??和||的区别是什么呢,看上去好像没有什么区别,但是||操作符会对左侧的数据进行Boolean类型转换,然后在判断true或false,再判断是否返回右侧的值,而空值合并操作符(??)不会。
注:这个新特性在chrome中暂时是不支持的,以后可能会支持,可能是我浏览器版本较低,其他浏览器暂时没有进行适配校验,大家感兴趣可以自行监测。
3.可选链操作符
当我们使用空值合并操作符判断当前属性是否存在的时候,我们就有问题了,如果一个对象深层嵌套呢,一个a对象,我们需要获取a.b.c,但是我们不确定a.b是否存在,如果用??的话又没法判断,用三目运算符虽然可以,但是略显麻烦,并且不严谨,这个时候我们可以来看看可选链操作符。
从上面的例子中我们可以看到,可选链操作符(?.)表示,如果左侧表达式有值,就会继续访问右侧的字段,用可选两可以大量简化类似繁琐的前置校验操作,而且更加安全,比如我么在请求接口时,需要判断是否有值,有的话再进行操作,传统写法一般都是if配置或非关系,有了可选链以后就会显得很方便。同样的,如果我们把可选链操作符和空值合并操作符搭配使用的话就能起到判断是否存在,并且直接过滤的功能。
注:up主在测试的时候同样发现,在chrome无法识别这个操作符,但是未来肯定会支持的,其次,可选链操作符只能用来判断是否存在,和是否进行下一层级属性的访问,并不能进行赋值操作。
4.BigInt
在js中有一个大家都很头疼的问题,那就是精度问题,最典型的就是0.1+0.2 !== 0.3,js中可以处理的最大数字范围时2^53,超出这个范围的就会丢失精度。
为了解决这个问题,ES11提供了一种新的数据类型:BingInt。使用BigInt的方式有两种:
1.在数字后面加n
2.使用BigInt函数
接下来在比较是就是正常的false了
注:BigInt是一种新的原始数据类型,不能与标准数字混合使用,在使用时尽可能避免通过调用BigInt函数的方式来实例化超大整型,因为传入的参数字面量还是Number类型的一次实例化,如果参数超出安全范围,同样会精度丢失。
5.动态导入
在一个工程化项目中,安装包后,可能只用到依赖中的某些资源,这个时候就需要按需加载了,可以让首屏渲染更快捷流畅。虽然现在前端基于webpack的按需引入已经很方便了,但是如果在js中可以直接使用是不是会更爽呢,所以ES11中提出了新的动态导入解决方案。
首先,导出一个函数:
接下来我们在另外的地方动态导入:
6.globalThis
js中在不同环境下获取全局对象的方式不同,nodejs中通过global,web中通过window或者self等等,甚至可以通过this获取,但是通过this获取时很危险的,this在js中严重依赖上下文,滥用this会增加获取全局对象的复杂性,并且在不同环境下this可能有所区别,但是我们需要写一个js文件,让它可以在node,web workers和浏览器中生效,这个时候全局变量的不统一另开发很苦恼,过去的解决方式是通过一个全局函数进行获取:
这个写法无疑是通用的,如果存在确实能获取到全局对象,但是看上去很不整洁,并且十分麻烦,每个项目中都需要定义这个globals。而在ES11中提供了新的globalThis,目的是提供一种标准化的方式去访问全局对象,这时候可以在任意上下文中获取全局对象自身,并且不用担心环境的问题。
7.Promise.all缺陷与Promise.allSettled
promise.all可以并发执行异步任务,这无疑让前端的异步操作可控性大大提高了,但是它最大的问题就是并发执行多个异步任务时,如果其中某个任务执行出现了异常,所有任务都会over,Promise会直接进入reject状态。
举个例子,页面中你需要同时请求多个接口,你在Promise.all中调用,但是这时一个接口服务异常了,那么这个时候你在其中请求接口的所有异步操作都会reject,这就导致页面拿不到渲染数据,严重的甚至会整个页面逻辑崩坏。
在ES11中,当我们处理多个promise时,尤其当他们相互依赖时,我们就需要记录每个事件在调试中发生的错误。使用Promise.allSettled,它会创建一个新的promise,在所有promise完成后返回一个包含每个promise结果的数组。
以上就是我对ES11新特性的一些总结,有遗漏或者不足的地方欢迎指正。