ES13新规终于发布了。JavaScript不是一种开源语言。它是一种需要按照ECMAScript标准规范编写的语言。TC39委员会负责讨论和批准新功能的发布。他们是谁?“ECMAInternational的TC39是一群JavaScript开发人员、实施者、学者等,他们与社区合作维护和发展JavaScript的定义。”—TC39.es他们的发布过程包括五个阶段,自2015年以来他们一直在进行年度发布,通常在春季进行。有两种方式来引用任何ECMAScript版本:按年份:这个新版本将是ES2022。从它的迭代次数来看:这个新版本将是第13次迭代,所以它可以被称为ES13。那么这个版本有什么新内容呢?我们可以为哪些功能感到兴奋?01.正则表达式匹配索引目前在JavaScript中使用JavaScriptRegexAPI时,只会返回匹配的起始索引。但是,对于一些特殊的高级场景,这还不够。作为这些规范的一部分,添加了一个特殊标志d。通过使用它,正则表达式API将返回一个二维数组作为名称索引的键。它包含每个匹配项的开始和结束索引。如果在正则表达式中捕获了任何命名组,它将在indices.groups对象中返回它们的开始/结束索引,并且命名组名称将是其键。//?带有'B'命名组的正则表达式captureconstexpr=/a+(?b+)+c/d;constresult=expr.exec("aaabbbc")//?显示开始-结束匹配+命名groupmatchconsole.log(result.indices);//打印[Array(2),Array(2),groups:{…}]//?显示命名为“B”的组matchconsole.log(result.indices.groups['B'])//prints[3,6]查看原提案,https://github.com/tc39/proposal-regexp-match-indices02,Top-levelawait在此提案之前,Top-levelawaitis不被接受,但是有一些变通方法可以模拟这种行为,但它有缺点。顶层的await特性让我们可以依赖模块来处理这些Promise。这是一个直观的功能。但是请注意,它可能会改变模块的执行顺序,如果一个模块依赖于另一个具有顶级await调用的模块,则该模块的执行将被挂起,直到承诺得到履行。让我们看一个例子://users.jsexportconstusers=awaitfetch('/users/lists');//usage.jsimport{users}from"./users.js";//?模块将等待用户在执行任何codeconsole.log(users)之前填写;在上面的示例中,引擎将等待用户完成操作,然后再执行usage.js模块上的代码。总而言之,这是一个很好的直观功能,需要小心使用,我们不要滥用它。在此处查看原始提案。https://github.com/tc39/proposal-top-level-await03,.at()长期以来一直要求JavaScript提供类似Python的数组负索引访问器。不要做array[array.length-1]而是简单地做array[-1]。这是不可能的,因为[]符号也用于JavaScript中的对象。被接受的提议采取了更实际的方法。数组对象现在将有一个方法来模拟上述行为。constarray=[1,2,3,4,5,6]//?当与正索引一起使用时,它等于[index]array.at(0)//1array[0]//1//?当与负索引一起使用,它模仿Python行为array.at(-1)//6array.at(-2)//5array.at(-4)//3请参阅原始提案,https://github.com/tc39/proposal-relative-indexing-method顺便说一句,既然我们在谈论数组,你知道你可以解构数组位置吗?constarray=[1,2,3,4,5,6];//?访问第三个位置的不同方式const{3:third}=array;//third=4array.at(3)//4array[3]//404,AccessibleObject.prototype.hasOwnProperty下面只是一个很好的简化,已经有了hasOwnProperty。但是,需要在我们要执行的查找实例中调用它。因此,许多开发人员最终这样做是很常见的:constx={foo:"bar"};//?从原型consthasOwnProperty=Object.prototype.hasOwnProperty中获取hasOwnProperty函数//?使用xcontextif(hasOwnProperty.call(x,"foo")){...}通过这些新规范,将hasOwn方法添加到Object原型。现在,我们可以简单地做:constx={foo:"bar"};//?使用新的Object方法if(Object.hasOwn(x,"foo")){...}参见原始提案,https://github.com/tc39/proposal-accessible-object-hasownproperty05,ErrorCause错误帮助我们识别应用程序的意外行为并对其做出反应,但是,了解深层嵌套错误的根本原因、正确处理它们可能变得具有挑战性,并且在捕获并重新抛出信息时,我们会丢失堆栈跟踪。关于如何处理这个问题没有明确的协议,考虑到任何错误处理,我们至少有3个选项:asyncfunctionfetchUserPreferences(){try{constusers=awaitfetch('//user/preferences').catch(err=>{//包装错误的最佳方法是什么?//1.thrownewError('Failedtofetchpreferences'+err.message);//2.constwrapErr=newError('Failedtofetchpreferences');//wrapErr.cause=err;//throwwrapErr;//3.classCustomErrorextendsError{//constructor(msg,cause){//super(msg);//this.cause=cause;//}//}//thrownewCustomError('Failedtofetchpreferences',err);})}}fetchUserPreferences();作为这些新规范的一部分,我们可以构造一个新错误并保留对获取的错误的引用。我们只是将对象{cause:err}传递给Errorconstructor。这一切都变得更简单、标准且易于理解深层嵌套的错误,让我们看一个示例:asyncfunctionfetchUserPreferences(){try{constusers=awaitfetch('//user/preferences').catch(err=>{newError('无法获取用户首选项,{cause:err});})}}fetcUserPreferences();了解有关该提案的更多信息,https://github.com/tc39/proposal-error-cause06,类字段在此版本之前,没有创建私有字段的正确方法,使用boost有一些解决方法,但它不是一个适当的私人领域。但现在很容易,我们只需要将#字符添加到我们的变量声明中。类Foo{#iteration=0;增量(){这个。#iteration++;}logIteration(){console.log(this.#iteration);}}constx=newFoo();//?未捕获的语法错误:私有字段“#iteration”必须在封闭类x中声明。#iteration//workx.increment();//workx.logIteration();拥有私有字段意味着我们拥有强大的封装边界,无法从外部访问类变量,这表明class关键字不再只是糖语法。我们还可以创建私有方法:classFoo{#iteration=0;#auditIncrement(){console.log('审计');}increment(){这个。#iteration++;这.#auditIncrement();}}constx=newFoo();//?未捕获的语法错误:私有字段“#auditIncrement”必须在封闭类x中声明。#auditIncrement//?worksx.increment();此功能类似于私有类静态块和人体工程学检查,我们将在接下来看到。了解有关提案的更多信息,https://github.com/tc39/proposal-class-fields07,ClassStaticBlock作为新规范的一部分,我们现在可以在任何类中包含静态块,它们只会运行一次,并且是在类的静态端装饰或执行某些字段初始化的好方法。我们不限于使用一个块,我们可以拥有任意多个块。//?将输出'一二三'classA{static{console.log('one');}static{console.log('two');}static{console.log('三');他们有不错的奖金,他们有访问私有字段的特权,你可以用他们做一些有趣的模式。让getPrivateField;类A{#privateField;构造函数(x){这个。#privateField=x;}static{//?它可以访问任何私有字段getPrivateField=(a)=>a.#privateField;}}consta=newA('foo');//?有效,foo被打印console.log(getPrivateField(a));如果我们尝试从实例对象的外部范围访问该私有变量,我们将获得一个无法从未声明它的类访问的对象。请阅读私有成员#privateField。了解有关提案的更多信息,https://github.com/tc39/proposal-class-static-block08,PrivateFields新的私有字段是一个很棒的特性,然而,检??查一些静态方法中的字段是否私有可能会变得很方便。试图在类范围之外调用它会导致我们之前看到的相同错误。Foo类{#brand;staticisFoo(obj){return#brandinobj;}}constx=newFoo();//?有效,它返回trueFoo.isFoo(x);//?有效,它返回falseFoo.isFoo({})//?未捕获的语法错误:私有字段'#brand'必须在x中的封闭类#brand中声明了解有关提案的更多信息。https://github.com/tc39/proposal-private-fields-in-in最后的想法这是一个有趣的版本,它提供了许多小而有用的功能,例如at、私有字段和错误原因。当然,错误原因使我们的日常错误跟踪任务更加清晰。一些高级功能,如顶级等待,需要在使用它们之前有很好的理解。它们可能会在您的代码执行中产生不必要的副作用。希望这篇文章能让你和我一样对新的ES2022规范感到兴奋,记得点赞关注我。-结尾-
