当前位置: 首页 > 科技观察

7令人兴奋的JavaScript新特性

时间:2023-03-21 23:28:10 科技观察

一个ECMAScript标准的制作过程包括从Stage0到Stage4的五个阶段,每个阶段都需要通过TC39的批准才能提交到下一阶段。本文介绍这些新功能处于Stage3或Stage4中,这意味着它们应该很快就会在浏览器和其他引擎中得到支持。1.类的私有变量最新的提议之一是在类中添加私有变量的方法。我们将使用#符号来表示类的私有变量。这消除了使用闭包来隐藏不想暴露给外界的私有变量的需要。classCounter{#x=0;#increment(){this.#x++;}onClick(){this.#increment();}}constc=newCounter();c.onClick();//普通c.#increment();//报错#修饰的成员变量或成员函数成为私有变量。如果您尝试在类之外访问它,则会抛出异常。此功能现已在最新版本的Chrome和Node.js中可用。二、optionalchainoperator你可能遇到过这样的情况:当你需要访问嵌套在对象内部几层的属性时,你会得到臭名昭著的错误Cannotreadproperty'stop'ofundefined,这时你不得不修改你的代码处理属性链中所有可能的未定义对象,例如:edProp=obj&&obj.first&&obj.first.second;在访问obj.first.second之前,必须确认obj和obj.first的值是非空的(并且不是undefined)。目的是防止错误发生。如果不验证obj和obj.first就直接访问obj.first.second,可能会出错。使用可选链,你可以通过简单地写来做同样的事情:letnestedProp=obj?.first?.second;如果obj或obj.first为null/undefined,表达式将短路计算并直接返回undefined。3.间隙合并算子在开发过程中,我们经常会遇到这样的场景:如果变量为空,则使用默认值。我们这样实现:letc=a?a:b//方法1letc=a||b//方法2这两种方法缺点很明显,会覆盖所有的false值,比如(0,'',false),这些值在某些情况下可能是有效输入。为了解决这个问题,有人提议创建一个“无效”合并运算符,用??表示。有了它,我们只在第一项为空或未定义时设置默认值。letc=a??b;//等价于letc=a!==undefined&&a!==null?a:b;例如下面的代码:constx=null;consty=x??500;console.log(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:CannotmixBigIntanandothertypes,useexplicitconversions该功能现已在最新版本的Chrome和Node.js中可用。五、静态字段它允许类有静态字段,类似于大多数OOP语言。可以使用静态字段代替枚举,以及私有字段。classColors{//publicstatic字段staticred='#ff0000';staticgreen='#00ff00';//privatestatic字段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';server.start();在这个例子中,在server.mjs中连接完成之前不会执行任何操作操作db.mjs。此功能现已在最新版本的Chrome中提供。7.WeakRef一般来说,在JavaScript中,对象引用是强保留的,也就是说只要你持有一个对象的引用,它就不会被垃圾回收。constref={x:42,y:51};//只要我们访问ref对象(或任何其他指向该对象的引用),这个对象就不会被垃圾回收目前在Javascript中,WeakMap和WeakSet都是弱引用objects唯一的方法:将对象作为键添加到WeakMap或WeakSet不会阻止它被垃圾收集。constwm=newWeakMap();{constref={};constmetaData='foo';wm.set(ref,metaData);wm.get(ref);//返回元数据}//在这个块范围内,我们没有A对ref对象的引用。//所以,虽然它是wm中的一个key,我们仍然可以访问它,但是它可以被垃圾回收。constws=newWeakSet();ws.add(ref);ws.has(ref);//返回trueJ??avaScript的WeakMap并不是真正的弱引用:只要key还活着,它实际上对其内容有强引用。只有在键被垃圾回收后,WeakMap才会弱引用其内容。WeakRef是提供真正弱引用的高级API。Weakref实例有一个deref方法,它返回被引用的原始对象,如果原始对象已被收集,则返回undefined。constcache=newMap();constsetValue=(key,obj)=>{cache.set(key,newWeakRef(obj));};constgetValue=(key)=>{constref=cache.get(key);if(ref){returnref.deref();}};//thiswilllookforthevalueinthecache//andrecalculateifit'missingconstfibonacciCached=(number)=>{constcached=getValue(number);if(cached)returncached;constsum=calculateFibonacci(number);setValue(number,sum);returnsum;};简而言之,JavaScript中的对象引用是强引用。WeakMap和WeakSet可以提供部分弱引用功能。如果你想在JavaScript中实现真正的弱引用,可以使用Wea??kRef和终结器(Finalizer)来实现。此功能现已在最新版本的Chrome和Node.js中可用。

最新推荐
猜你喜欢