前言一个ECMAScript标准的制作过程包括从Stage0到Stage4的五个阶段,每个阶段都需要经过TC39的批准才能提交到下一阶段。本文介绍这些新功能处于Stage3或Stage4,这意味着它们应该很快就会在浏览器和其他引擎中得到支持。更多优质文章请戳GitHub博客1.类的私有变量最新的提议之一是在类中添加私有变量的方法。我们将使用#符号来表示类的私有变量。这消除了使用闭包来隐藏不想暴露给外界的私有变量的需要。类计数器{#x=0;#increment(){这个。#x++;}onClick(){这个。#increment();}}constc=newCounter();c.onClick();//普通c.#increment();//报错#修饰的成员变量或成员函数成为私有变量。如果您尝试在类之外访问它,则会抛出异常。此功能现已在最新版本的Chrome和Node.js中可用。二、optionalchainoperator你可能遇到过这样的情况:当你需要访问嵌套在对象内部几层的属性时,你会得到臭名昭著的错误Cannotreadproperty'stop'ofundefined,这时你不得不修改你的代码处理属性链中所有可能的未定义对象,例如:letnestedProp=obj&&obj.first&&obj.first.second;在访问obj.first.second之前,obj和obj.first的值要被确认为非null(并且不是undefined)。目的是防止错误发生。如果不验证obj和obj.first就直接访问obj.first.second,可能会出错。使用可选链,您可以通过编写来做同样的事情:letnestedProp=obj?.first?.second;如果obj或obj.first为null/undefined,则表达式短路,直接返回undefined。3.间隙合并算子在开发过程中,我们经常会遇到这样的场景:如果变量为空,就会使用默认值。我们是这样实现的:让c=a?a:b//方法1letc=a||b//方法二这两种方法都有明显的缺点,它们会覆盖所有的假值,比如(0,'',false),这些值在某些情况下可能是有效输入。为了解决这个问题,有人提议创建一个“无效”合并运算符,用??表示。有了它,我们只在第一项为空或未定义时设置默认值。让c=a??b;//等价于letc=a!==undefined&&a!==null?一个:乙;例如下面的代码:constx=null;常量y=x??500;控制台日志(y);//500constn=0constm=n??9000;console.log(m)//04.BigIntJS数学不好的原因之一是大于2^53的数字,这使得处理相当大的数字变得非常困难。1234567890123456789*123;//->151851850485185200000//计算结果丢失精度还好BigInt(大整数)来解决这个问题。您可以在BigInt上使用与普通数字相同的运算符,例如+、-、/、*、%等。创建BigInt类型的值也非常简单,只需在数字后添加n即可。例如,123变为123n。也可以使用全局方法BigInt(value)进行转换,输入参数值为一个数字或一串数字。constaNumber=111;constaBigInt=BigInt(aNumber);aBigInt===111n//truetypeofaBigInt==='bigint'//truetypeof111//"number"typeof111n//"bigint"只需在数字n的末尾添加,即可正确计算大数:1234567890123456789n*123n;//->151851850485185185047n但是有一个问题,在大多数操作中,BigInt和Number不能混合使用。可以比较Numbers和BigInts,但不能将它们相加。1n<2//true1n+2//UncaughtTypeError:CannotmixBigIntandothertypes,useexplicitconversions此功能现已在最新版本的Chrome和Node.js中可用。五、静态字段它允许类有静态字段,类似于大多数OOP语言。可以使用静态字段代替枚举,以及私有字段。classColors{//公共静态字段staticred='#ff0000';静态绿色='#00ff00';//私有静态字段static#secretColor='#f0f0f0';}font.color=Colors.red;font.color=Colors.#secretColor;//Error此功能现在在最新版本的Chrome和Node.js中可用。6.顶层awaitES2017(ES8)中的async/await特性只允许在async函数中使用await关键字。新提案旨在允许在顶级内容中使用await关键字,例如,简化动态模块加载过程:conststrings=awaitimport(`/i18n/${navigator.language}`);此功能对于在浏览器控制台中调试诸如获取之类的异步内容很有用,而无需将其包装到异步函数中。另一种使用场景是可以在一个异步初始化的ES模块的顶层使用(比如建立数据库连接)。当导入这样一个“异步模块”时,模块系统将等待它被解析,然后再执行依赖于它的模块。这种处理异步初始化的方式比当前返回初始化承诺并等待它解决要容易得多。模块不知道它的依赖项是否是异步的。//db.mjsexportconstconnection=awaitcreateConnection();//server.mjsimport{connection}from'./db.mjs';服务器.start();在这个例子中,直到在server.mjs中完成连接才会对db.mjs做任何事情。此功能现已在最新版本的Chrome中提供。7.WeakRef一般来说,在JavaScript中,对象引用是强保留的,也就是说只要你持有一个对象的引用,它就不会被垃圾回收。constref={x:42,y:51};//只要我们访问ref对象(或任何其他指向这个对象的引用),这个对象就不会被垃圾回收目前在Javascript中,WeakMap和WeakSet是弱的引用对象唯一的方法:将对象作为键添加到WeakMap或WeakSet不会阻止它被垃圾收集。constwm=newWeakMap();{constref={};constmetaData='foo';wm.set(参考,元数据);wm.get(参考);//返回元数据}//在这个块的范围内,我们不再有对ref对象的引用。//所以,虽然它是wm中的一个key,我们仍然可以访问它,但是它可以被垃圾回收。constws=newWeakSet();ws.add(ref);ws.has(ref);//返回trueJavaScript的WeakMap并不是真正的弱引用:事实上,只要key还活着,它就强引用它的内容。只有在键被垃圾回收后,WeakMap才会弱引用其内容。WeakRef是提供真正弱引用的高级API。Weakref实例有一个deref方法,它返回被引用的原始对象,如果原始对象已被收集,则返回undefined。常量缓存=新地图();constsetValue=(key,obj)=>{cache.set(key,newWeakRef(obj));};constgetValue=(key)=>{constref=cache.get(key);如果(ref){返回ref.deref();}};//这将查找缓存中的值//并在缺少时重新计算constfibonacciCached=(number)=>{constcached=getValue(number);如果(缓存)返回缓存;constsum=calculateFibonacci(数字);设置值(数字,总和);返回总和;};总而言之,JavaScript中的对象引用属于强引用,WeakMap和WeakSet可以提供部分弱引用功能,如果想在JavaScript中实现真正的弱引用,可以使用WeakRef和终结器(Finalizer)一起实现。此功能现已在最新版本的Chrome和Node.js中可用。文末欢迎志同道合的朋友加入技术交流群!向大家推荐一款好用的BUG监控工具Fundebug,欢迎免费试用!欢迎关注公众号:前端工匠,让我们一起见证你的成长!参考文章7令人兴奋的你需要知道的JavaScript新特性ES2020即将到来的你现在可以使用的JavaScript新特性精读《What's new in javascript》【RPU-A】新的Top-levelawaitproposal如何实现JS真正意义上的弱引用?
