2022發(fā)布ECMAScript新特性盤點_第1頁
2022發(fā)布ECMAScript新特性盤點_第2頁
2022發(fā)布ECMAScript新特性盤點_第3頁
2022發(fā)布ECMAScript新特性盤點_第4頁
2022發(fā)布ECMAScript新特性盤點_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第2022發(fā)布ECMAScript新特性盤點目錄引言1.Top-levelAwait2.Object.hasOwn()3.at()4.error.cause5.正則表達(dá)式匹配索引6.類的實例成員(1)公共實例字段(2)私有實例字段、方法和訪問器(3)靜態(tài)公共字段(4)靜態(tài)私有字段和方法(5)類靜態(tài)初始化塊

引言

2025年6月22日,第123屆ECMA大會批準(zhǔn)了ECMAScript2025語言規(guī)范,這意味著它現(xiàn)在正式成為標(biāo)準(zhǔn)。下面就來看看ECMAScript2025新增了哪些特性!

總覽:

Top-levelAwaitObject.hasOwn()at()error.cause正則表達(dá)式匹配索引類的實例成員

1.Top-levelAwait

在ES2017中,引入了async函數(shù)和await關(guān)鍵字,以簡化Promise的使用,但是await關(guān)鍵字只能在async函數(shù)內(nèi)部使用。嘗試在異步函數(shù)之外使用await就會報錯:

SyntaxError-SyntaxError:awaitisonlyvalidinasyncfunction。

頂層await允許我們在async函數(shù)外面使用await關(guān)鍵字。它允許模塊充當(dāng)大型異步函數(shù),通過頂層await,這些ECMAScript模塊可以等待資源加載。這樣其他導(dǎo)入這些模塊的模塊在執(zhí)行代碼之前要等待資源加載完再去執(zhí)行。

由于await僅在async函數(shù)中可用,因此模塊可以通過將代碼包裝在async函數(shù)中來在代碼中包含await:

//a.js

importfetchfrom"node-fetch";

letusers;

exportconstfetchUsers=async()={

constresp=awaitfetch('/users');

users=resp.json();

fetchUsers();

export{users};

//usingAwait.js

import{users}from'./a.js';

console.log('users:',users);

console.log('usingAwaitmodule');

我們還可以立即調(diào)用頂層async函數(shù)(IIAFE):

importfetchfrom"node-fetch";

(async()={

constresp=awaitfetch('/users');

users=resp.json();

})();

export{users};

這樣會有一個缺點,直接導(dǎo)入的users是undefined,需要在異步執(zhí)行完成之后才能訪問它:

//usingAwait.js

import{users}from'./a.js';

console.log('users:',users);//undefined

setTimeout(()={

console.log('users:',users);

},100);

console.log('usingAwaitmodule');

當(dāng)然,這種方法并不安全,因為如果異步函數(shù)執(zhí)行花費的時間超過100毫秒,它就不會起作用了,users仍然是undefined。

另一個方法是導(dǎo)出一個promise,讓導(dǎo)入模塊知道數(shù)據(jù)已經(jīng)準(zhǔn)備好了:

//a.js

importfetchfrom"node-fetch";

exportdefault(async()={

constresp=awaitfetch('/users');

users=resp.json();

})();

export{users};

//usingAwait.js

importpromise,{users}from'./a.js';

promise.then(()={

console.log('usingAwaitmodule');

setTimeout(()=console.log('users:',users),100);

雖然這種方法似乎是給出了預(yù)期的結(jié)果,但是有一定的局限性:導(dǎo)入模塊必須了解這種模式才能正確使用它。

而頂層await就可以解決這些問題:

//a.js

constresp=awaitfetch('/users');

constusers=resp.json();

export{users};

//usingAwait.js

import{users}from'./a.mjs';

console.log(users);

console.log('usingAwaitmodule');

頂級await在以下場景中將非常有用:

動態(tài)加載模塊:

conststrings=awaitimport(`/i18n/${navigator.language}`);

資源初始化:

constconnection=awaitdbConnector();

依賴回退:

lettranslations;

try{

translations=awaitimport('https://app.fr.json');

}catch{

translations=awaitimport('https://fallback.en.json');

該特性的瀏覽器支持如下:

2.Object.hasOwn()

在ES2025之前,可以使用Ototype.hasOwnProperty()來檢查一個屬性是否屬于對象。

Object.hasOwn特性是一種更簡潔、更可靠的檢查屬性是否直接設(shè)置在對象上的方法:

constexample={

property:'123'

console.log(Ototype.hasOwnProperty.call(example,'property'));

console.log(Object.hasOwn(example,'property'));

該特性的瀏覽器支持如下:

3.at()

at()是一個數(shù)組方法,用于通過給定索引來獲取數(shù)組元素。當(dāng)給定索引為正時,這種新方法與使用括號表示法訪問具有相同的行為。當(dāng)給出負(fù)整數(shù)索引時,就會從數(shù)組的最后一項開始檢索:

constarray=[0,1,2,3,4,5];

console.log(array[array.length-1]);//5

console.log(array.at(-1));//5

console.log(array[array.lenght-2]);//4

console.log(array.at(-2));//4

除了數(shù)組,字符串也可以使用at()方法進(jìn)行索引:

conststr="helloworld";

console.log(str[str.length-1]);//d

console.log(str.at(-1));//d

4.error.cause

在ECMAScript2025規(guī)范中,newError()中可以指定導(dǎo)致它的原因:

functionreadFiles(filePaths){

returnfilePaths.map(

(filePath)={

try{

//···

}catch(error){

thrownewError(

`Whileprocessing${filePath}`,

{cause:error}

5.正則表達(dá)式匹配索引

該特性允許我們利用d字符來表示我們想要匹配字符串的開始和結(jié)束索引。以前,只能在字符串匹配操作期間獲得一個包含提取的字符串和索引信息的數(shù)組。在某些情況下,這是不夠的。因此,在這個規(guī)范中,如果設(shè)置標(biāo)志/d,將額外獲得一個帶有開始和結(jié)束索引的數(shù)組。

constmatchObj=/(a+)(b+)/d.exec('aaaabb');

console.log(matchObj[1])//'aaaa'

console.log(matchObj[2])//'bb'

由于/d標(biāo)識的存在,matchObj還有一個屬性.indices,它用來記錄捕獲的每個編號組:

console.log(matchObj.indices[1])//[0,4]

console.log(matchObj.indices[2])//[4,6]

我們還可以使用命名組:

constmatchObj=/(asa+)(bsb+)/d.exec('aaaabb');

console.log(matchObj.groups.as);//'aaaa'

console.log(matchObj.groups.bs);//'bb'

這里給兩個字符匹配分別命名為as和bs,然后就可以通過groups來獲取到這兩個命名分別匹配到的字符串。

它們的索引存儲在matchObj.indices.groups中:

console.log(matchObj.indices.groups.as);//[0,4]

console.log(matchObj.indices.groups.bs);//[4,6]

匹配索引的一個重要用途就是指向語法錯誤所在位置的解析器。下面的代碼解決了一個相關(guān)問題:它指向引用內(nèi)容的開始和結(jié)束位置。

constreQuoted=/“([^”]+)”/dgu;

functionpointToQuotedText(str){

conststartIndices=newSet();

constendIndices=newSet();

for(constmatchofstr.matchAll(reQuoted)){

const[start,end]=match.indices[1];

startIndices.add(start);

endIndices.add(end);

letresult='';

for(letindex=0;indexstr.length;index++){

if(startIndices.has(index)){

result+='[';

}elseif(endIndices.has(index+1)){

result+=']';

}else{

result+='';

returnresult;

console.log(pointToQuotedText('Theysaid“hello”and“goodbye”.'));

//'[][]'

6.類的實例成員

(1)公共實例字段

公共類字段允許我們使用賦值運算符(=)將實例屬性添加到類定義中。下面是一個計數(shù)器的例子:

importReact,{Component}from"react";

exportclassIncrementorextendsComponent{

constructor(){

super();

this.state={

count:0,

this.increment=this.increment.bind(this);

increment(){

this.setState({count:this.state.count+1});

render(){

return(

buttonthis.increment}Increment:{this.state.count}/button

在這個例子中,在構(gòu)造函數(shù)中定義了實例字段和綁定方法,通過新的類語法,可以使代碼更加直觀。新的公共類字段語法允許我們直接將實例屬性作為屬性添加到類上,而無需使用構(gòu)造函數(shù)方法。這樣就簡化了類的定義,使代碼更加簡潔、可讀:

importReactfrom"react";

exportclassIncrementorextendsReact.Component{

state={count:0};

increment=()=this.setState({count:this.state.count+1});

render=()=(

buttonthis.increment}Increment:{this.state.count}/button

有些小伙伴可能就疑問了,這個功能很早就可以使用了呀。但是它現(xiàn)在還不是標(biāo)準(zhǔn)的ECMAScript,默認(rèn)是不開啟的,如果使用create-react-app創(chuàng)建React項目,那么它默認(rèn)是啟用的,否則我們必須使用正確的babel插件才能正常使用(@babel/preset-env)。

下面來看看關(guān)于公共實例字段的注意事項:

公共實例字段存在于每個創(chuàng)建的類實例上。它們要么是在Object.defineProperty()中添加,要么是在基類中的構(gòu)造時添加(構(gòu)造函數(shù)主體執(zhí)行之前執(zhí)行),要么在子類的super()返回之后添加:

classIncrementor{

count=0

constinstance=newIncrementor();

console.log(instance.count);//0

未初始化的字段會自動設(shè)置為undefined:

classIncrementor{

count

constinstance=newIncrementor();

console.assert(instance.hasOwnProperty('count'));

console.log(instance.count);//undefined

可以進(jìn)行字段的計算:

constPREFIX='main';

classIncrementor{

[`${PREFIX}Count`]=0

constinstance=newIncrementor();

console.log(instance.mainCount);//0

(2)私有實例字段、方法和訪問器

默認(rèn)情況下,ES6中所有屬性都是公共的,可以在類外檢查或修改。下面來看一個例子:

classTimeTracker{

name='zhangsan';

project='blog';

hours=0;

setaddHours(hour){

this.hours+=hour;

gettimeSheet(){

return`${}works${this.hours||'nothing'}hourson${ject}`;

letperson=newTimeTracker();

person.addHours=2;//標(biāo)準(zhǔn)setter

person.hours=4;//繞過setter進(jìn)行設(shè)置

person.timeSheet;

可以看到,在類中沒有任何措施可以防止在不調(diào)用setter的情況下更改屬性。

而私有類字段將使用哈希#前綴定義,從上面的示例中,可以修改它以包含私有類字段,以防止在類方法之外更改屬性:

classTimeTracker{

name='zhangsan';

project='blog';

#hours=0;//私有類字段

setaddHours(hour){

this.#hours+=hour;

gettimeSheet(){

return`${}works${this.#hours||'nothing'}hourson${ject}`;

letperson=newTimeTracker();

person.addHours=4;//標(biāo)準(zhǔn)setter

person.timeSheet//zhangsanworks4hoursonblog

當(dāng)嘗試在setter方法之外修改私有類字段時,就會報錯:

person.hours=4//ErrorPrivatefield'#hours'mustbedeclaredinanenclosingclass

還可以將方法或getter/setter設(shè)為私有,只需要給這些方法名稱前面加#即可:

classTimeTracker{

name='zhangsan';

project='blog';

#hours=0;//私有類字段

set#addHours(hour){

this.#hours+=hour;

get#timeSheet(){

return`${}works${this.#hours||'nothing'}hourson${ject}`;

constructor(hours){

this.#addHours=hours;

console.log(this.#timeSheet);

letperson=newTimeTracker(4);//zhangsanworks4hoursonblog

由于嘗試訪問對象上不存在的私有字段會發(fā)生異常,因此需要能夠檢查對象是否具有給定的私有字段。可以使用in運算符來檢查對象上是否有私有字段:

classExample{

#field

staticisExampleInstance(object){

return#fieldinobject;

(3)靜態(tài)公共字段

在ES6中,不能在類的每個實例中訪問靜態(tài)字段或方法,只能在原型中訪問。ES2025提供了一種在JavaScript中使用static關(guān)鍵字聲明靜態(tài)類字段的方法。下面來看一個例子:

classShape{

staticcolor='blue';

staticgetColor(){

returnthis.color;

getMessage(){

return`color:${this.color}`;

可以從類本身訪問靜態(tài)字段和方法:

console.log(Shape.color);//blue

console.log(Shape.getColor());//blue

console.log('color'inShape);//true

console.log('getColor'inShape);//true

console.log('getMessage'inShape);//false

實例不能訪問靜態(tài)字段和方法:

constshapeInstance=newShape();

console.log(shapeInstance.color);//undefined

console.log(shapeInstance.getColor);//undefined

console.log(shapeInstance.getMessage());//color:undefined

靜態(tài)字段只能通過靜態(tài)方法訪問:

console.log(Shape.getColor());//blue

console.log(Shape.getMessage());//TypeError:Shape.getMessageisnotafunction

這里的Shape.getMessage()就報錯了,因為getMessage不是一個靜態(tài)函數(shù),所以它不能通過類名Shape訪問??梢酝ㄟ^以下方式來解決這個問題:

getMessage(){

return`color:${Shape.color}`;

靜態(tài)字段和方法是從父類繼承的:

classRectangleextendsShape{}

console.log(Rectangle.color);//blue

console.log(Rectangle.getColor());//blue

console.log('color'inRectangle);//true

console.log('getColor'inRectangle);//true

console.log('getMessage'inRectangle);//false

(4)靜態(tài)私有字段和方法

與私有實例字段和方法一樣,靜態(tài)私有字段和方法也使用哈希(#)前綴來定義:

classShape{

static#color='blue';

static#getColor(){

returnthis.#color;

getMessage(){

return`color:${Shape.#getColor()}`;

constshapeInstance=newShape();

shapeInstance.getMessage();//color:blue

私有靜態(tài)字段有一個限制:只有定義私有靜態(tài)字段的類才能訪問該字段。這可能在使用this時導(dǎo)致出乎意料的情況:

classShape{

static#color='blue';

static#getColor(){

returnthis.#color;

staticgetMessage(){

return`color:${this.#color}`;

getMessageNonStatic(){

return`color:${this.#getColor()}`;

classRectangleextendsShape{}

console.log(Rectangle.getMessage());//UncaughtTypeError:Cannotreadprivatemember#colorfromanobjectwhoseclassdidnotdeclareit

constrectangle=newRectangle();

console.log(rectangle.getMessageNonStatic());//TypeError:Cannotreadprivatemember#getColorfromanobjectwhoseclassdidnotdeclareit

在這個例子中,this指向的是Rectangle類,它無權(quán)訪問私有字段#color。當(dāng)我們嘗試調(diào)用Rectangle.getMessage()時,它無法讀取#color并拋出了TypeError??梢赃@樣來進(jìn)行修改:

classShape{

static#color='blue';

static#getColor(){

returnthis.#color;

staticgetMessage(){

return`${Shape.#color}`;

getMessageNonStatic(){

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論