当前位置: 首页 > Web前端 > JavaScript

精读《class static block》

时间:2023-03-27 17:10:12 JavaScript

class-static-block提案于2021年9月1日进入第4阶段,是基于Classenhancement的提案。本周我们将与文章ES2022特性:类静态初始化块一起讨论此特性。大纲为什么我们需要类静态块的语法?这样做的原因之一是需要灵活地分配Class静态变量。以下面的例子,如果我们要批量初始化Class内部的静态变量,我们不得不写一个无用的_变量来做初始化逻辑:classTranslator{statictranslations={yes:'ja',no:'nein',也许:'vielleicht',};静态英语单词=[];静态germanWords=[];static_=initializeTranslator(//(A)this.translations,this.englishWords,this.germanWords);}functioninitializeTranslator(translations,englishWords,germanWords){for(const[english,german]ofObject.entries(translations))}{englishWords.push(英语);germanWords.push(德语);}}为什么我们要在外面写initializeTranslator?只是因为Class内部不能写代码块,但是这样就造成了一个严重的问题,就是外部函数无法访问Class内部的属性,所以需要做一堆无聊的传值。从这个例子我们可以看出,为了自定义一段静态变量的初始化逻辑,我们需要做两个妥协:外部定义一个函数,接受大量的Class成员变量参数。在Class内部定义一个无意义的变量_来启动函数逻辑。这真是无代码追求。如果把Class内部的这些逻辑去掉,岂不是更简洁了?这是类静态块功能:classTranslator{statictranslations={yes:'ja',no:'nein',maybe:'vielleicht',};静态英语单词=[];静态germanWords=[];static{//(A)for(const[english,german]ofObject.entries(this.translations)){this.englishWords.push(english);this.germanWords.push(德语);}}}可以看到,static关键字后面没有跟变量,而是直接跟一个代码块,这是类静态块语法的特点。在这个代码块内部,Class的所有成员变量都可以通过this访问,包括#private变量。原来这个特性的使用介绍就结束了,最后说一个细节,就是执行顺序。即所有静态变量或块按顺序执行,父类先执行: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'所以Class中允许有多个类静态块,父类和子类也可以有,不同的执行顺序结果会不同,这个选择是给用户的,因为执行顺序和写在同样的顺序。精读结合提案,classstaticblock还有一个动机,就是提供访问私有变量的机制:letgetX;exportclassC{#xconstructor(x){this.#x={data:x};}static{//getX有特权访问#xgetX=(obj)=>obj.#x;}}exportfunctionreadXData(obj){returngetX(obj).data;}理论上无论如何外界都访问不到Class的私有变量,但是上面例子中的readXData是没问题的,运行起来也不会报错,因为整个过程是合法的。最重要的原因是类静态块可以同时访问私有变量和全局变量,所以可以用它做一个“由内到外的配合”。不过,我并不认为这是一个好主意,而是更像是一个“BUG”,因为任何突破法规都会为可维护性埋下隐患,除非这个特性被用在稳定的工具和框架层中,为了一些方便性工作,这最终增强了应用程序编码体验,对于这种用法是可以接受的。最后,应该认识到类静态块本质上并没有增加新的功能。我们可以用普通的静态变量代替,但是写起来不自然,所以这个特性可以理解为对缺陷的补充,或者语法上的改进。总结一般来说,类静态块在Class中创建一个blockscope,它有访问Class内部私有变量的权限,并且这个blockscope只在引擎被调用时初始化一次,是一种比较方便的语法.原文底部有反对意见,说这是JS的并发症,也有诸如JS越来越像Java之类的声音,但我同意作者的观点,即,Js中的Class并不是全部,现在越来越多的代码使用函数式语法,即使在使用Class的场景下也会有大量的函数声明,所以classstaticblock的提法对于开发者来说其实是不太能感知的。讨论地址为:Jingdu《class static block》·Issue#351·dt-fe/weekly想参与讨论的请戳这里,每周都有新话题,周末或周一发布。前端精读——帮你过滤靠谱的内容。关注前端精读微信公众号版权声明:免费转载-非商业-非衍生保留属性(CreativeCommons3.0License)