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

类静态初始化块即将包含在ES2022中,快来看看

时间:2023-03-22 12:02:59 科技观察

RonBuckton的ECMAScript提案“类静态初始化块”已经进入第四阶段,计划包含在ECMAScript2022中。为了创建一个一个类的实例,在JavaScript中有两种构造:字段:创建(并可选地初始化)实例属性。构造函数:在设置完成之前执行的代码块。对于类静态部分的设置,我们只有静态字段。ECMAScript建议为类引入静态初始化块,它对静态类的作用大致与构造函数对实例的作用相同。1.为什么类中需要静态块?设置静态字段时,使用外部函数通常也能很好地工作:(this.translations);}functionextractEnglish(translations){returnObject.keys(translations);}functionextractGerman(translations){returnObject.values(translations);}使用外部函数extractEnglish()和extractGerman()在这种情况下效果很好,因为我们可以看到它们是从类内部调用的,并且它们完全独立于类。如果我们想同时设置两个静态字段,事情就变得不那么优雅了。classTranslator{statictranslations={yes:'ja',no:'nein',maybe:'vielleicht',};staticenglishWords=[];staticgermanWords=[];static_=initializeTranslator(//(A)this.translations,this.englishWords,this.germanWords);}functioninitializeTranslator(translations,englishWords,germanWords){for(const[english,german]ofObject.entries(translations)){englishWords.push(english);germanWords.push(german);}}这一时间,有好几个问题。调用initializeTranslator()是一个额外的步骤,要么在创建类之后,要么在类外执行。或者通过变通方法(A行)来实现。initializeTranslator()无法访问翻译器的私有数据。使用建议的静态块(A行),我们有一个更优雅的解决方案。classTranslator{statictranslations={yes:'ja',no:'nein',maybe:'vielleicht',};staticenglishWords=[];staticgermanWords=[];static{//(A)for(const[english,german]ofObject.entries(this.translations)){this.englishWords.push(english);this.germanWords.push(german);}}}2.一个更复杂的例子在JavaScript中实现枚举的一种方法是通过超类EnumclassEnum{staticcollectStaticFields(){//Staticmethodsarenotenumerableandthusignoredthis.enumKeys=Object.keys(this);}}classColorEnumextendsEnum{staticred=Symbol('red');staticgreen=Symbol('green');staticblue=Symbol('blue');static_=this.collectStaticFields();//(A)staticlogColors(){for(constenumKeyofthis.enumKeys){//(B)console.log(enumKey);}}}ColorEnum.logColors();//Output://'red'//'green'//'blue'我们需要收集静态字段,以便我们可以迭代枚举项的键(B行)。这是创建所有静态字段后的最后一步。我们再次使用变通方法(A行),静态块会更优雅。3.细节静态块的具体内容比较符合逻辑(相比之下,实例成员的规则更复杂):每个类可以有多个静态块。静态块的执行与静态字段初始值设定项的执行交织在一起。超类的静态成员在子类的静态成员之前执行。以下代码显示了这些规则:classSuperClass{staticsuperField1=console.log('superField1');static{assert.equal(this,SuperClass);console.log('staticblock1SuperClass');}staticsuperField2=console.log('superField2');static{console.log('staticblock2SuperClass');}}classSubClassextendsSuperClass{staticsubField1=console.log('subField1');static{assert.equal(this,SubClass);console.log('staticblock1SubClass');}staticsubField2=console.log('subField2');static{console.log('staticblock2SubClass');}}//Output://'superField1'//'staticblock1SuperClass'//'superField2'//'staticblock2SuperClass'//'subField1'//'staticblock1SubClass'//'subField2'//'staticblock2SubClass'4.引擎中的支持类静态块V8:在v9.4.146中未标记(来源)SpiderMonkey:在v92中的标记后面,意图在v93中未标记地发布(来源)TypeScript:v4.4(来源)5.JS是否变得太像Java和/或太混乱了?这是一个不会与其他功能竞争的小功能。我们已经可以通过static_=...字段运行静态代码。静态块意味着不再需要此解决方法。除此之外,类只是JavaScript程序员腰带上的众多工具之一。我们中的一些人使用它,另一些人不使用它,而且有很多选择。即使是使用类的JS代码也经常使用函数并且趋向于轻量级。6.小结类的静态块是一个比较简单的功能,它完成了一个类的静态功能。粗略地说,它是实例构造函数的静态版本。它主要在我们需要设置多个静态字段时有用。作者:Dr.AxelRauschmayer译者:前端小智来源:2ality原文:https://2ality.com/2021/09/class-static-block.html