.. ES9中5个最具变革性的JavaScript特性(大迁世界2024年08月01日文章)_众股360

您的位置 : 首页 > 公众号 > 大迁世界

ES9中5个最具变革性的JavaScript特性(大迁世界2024年08月01日文章)

分享到:
作者:大迁世界 | 更新时间:2024-08-06 11:30:17

前端岗位内推来了过去10年里,JavaScript取得了长足进步,每年都有全新的功能升级。今天,我们来看看早期ES9中引入的5个最重要的特性,看看你是否错过了其中一些。1. 异步生成器和迭代异步生成器是ES9中一个强大的特性。就像普通的生成...

A股板块轮动加剧,跨年大妖来袭,这几只票主力已明显介入!微信搜索关注【研讯小组】公众号(可长按复制),回复666,领取代码!

前端岗位内推来了

过去10年里,JavaScript取得了长足进步,每年都有全新的功能升级

今天,我们来看看早期ES9中引入的5个最重要的特性,看看你是否错过了其中一些。

1. 异步生成器和迭代

异步生成器是ES9中一个强大的特性。

就像普通的生成器,但现在它可以在异步工作(如网络请求)后弹出值:

function*asyncGenerator(){
yieldnewPromise((resolve)=>
setTimeout(()=>resolve('donethis✅'),2000)
);
yieldnewPromise((resolve)=>
setTimeout(()=>resolve('donethat✅'),3000)
);
}

当我们调用.next()时,我们会得到一个Promise

constasyncGen=asyncGenerator();

asyncGen.next().value.then(console.log);
asyncGen.next().value.then(console.log);

这是一个强大的工具,可以在web应用中以结构化+可读的方式流式传输数据 — 看看这个为类似YouTube的视频分享应用缓冲和流式传输数据的函数:

asyncfunction*streamVideo({id}){
letendOfVideo=false;
constdownloadChunk=async(sizeInBytes)=>{
constresponse=awaitfetch(
`api.example.com/videos/${id}`
);
const{chunk,done}=awaitresponse.json();
if(done)endOfVideo=true;
returnchunk;
};
while(!endOfVideo){
constbufferSize=500*1024*1024;
yieldawaitdownloadChunk(bufferSize);
}
}

现在要消费这个生成器,我们将使用for await of — 异步迭代:

forawait(constchunkofstreamVideo({id:2341})){
//processvideochunk
}

我想知道实际的YouTube JavaScript代码是否使用了这样的生成器?

2.对象的剩余/展开运算符

毫无疑问,你在某处遇到过现代的展开语法。

这是一种快速且不可变地克隆数组的天才方法:

constcolors=['','',''];

console.log([...colors,'']);
//['','','','']

在ES6之前我们从未有过它,现在它无处不在。

Redux就是一个重要的例子:

exportdefaultfunctionuserState(state=initialUserState,action){
console.log(arr);
switch(action.type){
caseADD_ITEM:
return{
...state,
arr:[...state.arr,action.newItem]
};
default:
returnstate;
}
}

从ES9开始,它也适用于对象:

constinfo={
name:'CodingBeauty',
site:'codingbeautydev.com',
};

console.log({...info,theme:''});

/*Output:
{
name:'CodingBeauty',
site:'codingbeautydev.com',
theme:''
}
*/

覆盖属性:

constlangs={
j:'java',
c:'c++',
};

console.log({...langs,j:'javascript'});

//Output:{j:'javascript',c:'c++'}

这使得它特别适合在默认值的基础上构建,尤其是在制作公共实用程序时。

或者像我用Material UI定制默认主题那样:

使用展开语法,你甚至可以去掉不想在副本中出现的对象属性。

constcolors={
yellow:'',
blue:'',
red:'',
};

const{yellow,...withoutYellow}=colors;

console.log(withoutYellow);

//Output:{blue:'',red:''}

这就是如何以不可变的方式从对象中移除属性。

3. String.raw

当我使用String.raw时,我是在说:只给我我给你的东西。不要处理任何东西。不要动那些转义字符:

不再需要转义反斜杠,我们不用写:

constfilePath='C:\\Code\\JavaScript\\tests\\index.js';

console.log(`Thefilepathis${filePath}`);

//Output:ThefilepathisC:\Code\JavaScript\tests\index.js

而是写:

constfilePath=String.raw`C:\Code\JavaScript\tests\index.js`;

console.log(`Thefilepathis${filePath}`);

//Output:ThefilepathisC:\Code\JavaScript\tests\index.js

非常适合编写带有大量这些反斜杠的正则表达式:

像这样但更糟:

从这个✅:

constpatternString='The(\\w+)is(\\d+)';
constpattern=newRegExp(patternString);

constmessage='Thenumberis100';

console.log(pattern.exec(message));
//['Thenumberis100','number','100']

到这个✅:

constpatternString=String.raw`The(\w+)is(\d+)`;
constpattern=newRegExp(patternString);

constmessage='Thenumberis100';

console.log(pattern.exec(message));
//['Thenumberis100','number','100']

所以"raw"意味着未处理的。

这就是为什么我们有String.raw()但没有String.cooked()

4. 复杂的正则表达式特性

说到正则表达式,ES9并没有让人失望。

它完全装载了最先进的正则表达式特性,用于高级字符串搜索和替换。

向后查找断言

这是一个新特性,用于确保只有某个特定模式出现在你要搜索的内容之前:

  • 正向后查找:白名单 ?<=pattern

  • 负向后查找:黑名单 ?

conststr="It'sjust$5,andIhave€20and£50";

//Onlymatchnumbersequenceif$comesfirst
constregexPos=/(?<=\$)\d+/g;

console.log(str.match(regexPos));//['5']

constregexNeg=/(?
console.log(str.match(regexNeg));//['20','50']

命名捕获组

捕获组一直是正则表达式中最宝贵的特性之一,用于以复杂的方式转换字符串。

conststr='Thecatsatonamap';

//$1->[a-z]
//$2->a
//$3->t

//()indicatesgroup
str.replace(/([a-z])(a)(t)/g,'$1*$3');
//->Thec*ts*tonamap

通常,这些组按照它们在正则表达式中的相对位置命名:1, 2, 3...

但这使得理解和更改那些愚蠢的长正则表达式变得更加困难。

所以ES9通过?来命名捕获组解决了这个问题:

conststr='Thecatsatonamap';

//left&right
console.log(str.replace(/(?[a-z])(a)(?t)/g,'$*$'));

//->Thec*ts*tonamap

1111111

你知道当VS Code中出现错误时,你可以快速Alt + 点击跳转到错误发生的确切位置吗?

111

VS Code使用捕获组使文件名可点击,从而实现这种快速导航。

我想它大概是这样的:

//Thestupidlylongregex
constregex=/(?[a-z]:[a-z].(?:?:\\/|(?:\\/?)))[\w\-]+):(?\d+):(?\d+)/gi;

//✅String.raw!
constfilePoint=String.raw`C:\coding-beauty\coding-beauty-javascript\index.js:3:5`;

constextractor=/(?[a-z]:[a-z].(?:?:\\/|(?:\\/?)))[\w\-]+):(?\d+):(?\d+)/i;
const[path,lineStr,charStr]=filePoint
.match(regex)[0]
.match(extractor)
.slice(1,4);

constline=Number(lineStr);

constchar=Number(charStr);

console.log({path,line,char});

//ReplaceallfilePointwith

5. Promise.finally

最后我们有了Promise.finally 。

你知道finally总是会运行一些代码,无论是否有错误吗?

functionstartBodyBuilding(){
if(Math.random()>0.5){
thrownewError("I'mtired");
}
console.log('Offtothegym️‍♂️');
}

try{
startBodyBuilding();
}catch{
console.log('Stoppedexcuse');
}finally{
console.log("I'mgoing!‍♂️");
}

所以Promise.finally就像那样,但是用于异步任务:

asyncfunctionstartBodyBuilding(){
awaitthink();
if(Math.random()>0.5){
thrownewError("I'mtired");
}
console.log('Offtothegym️‍♂️');
}

startBodyBuilding()
.then(()=>{
console.log('Started✅');
})
.catch(()=>{
console.log('Noexcuses');
})
.finally(()=>{
console.log("I'mgoing!‍♂️");
});

Promise.finally()最大的优点是当你链接许多Promise时:

它也能很好地与Promise链一起工作:

getFruitApiUrl().then((url)=>{
returnfetch(url)
.then((res)=>res.json())
.then((data)=>{
fruits.push(data);
})
.catch((err)=>{
console.error(err);
})
.finally(()=>{
console.log(fruits);
});
});

这是由ES9带来的。

最后的思考

ES9标志着JavaScript的一个重大飞跃,引入了几个对现代开发至关重要的特性。使你能够快速编写更清晰、更简洁、更富表现力的代码。


最后:

CSS技巧与案例详解

vue2与vue3技巧合集

VueUse源码解读

A股板块轮动加剧,跨年大妖来袭,这几只票主力已明显介入!微信搜索关注【研讯小组】公众号(可长按复制),回复666,领取代码!

本站内容转载请注明来源并提供链接,数据来自互联网,仅供参考。如发现侵权行为,请联系我们删除涉嫌侵权内容。

展开

相关文章

更多>>

关于本站 反馈中心 版权声明 网站地图

  版权投诉请发邮件到1191009458#qq.com(把#改成@),我们会尽快处理

  Copyright©2023-2024众股360(www.zgu360.com).AllReserved|备案号:湘ICP备2023009521号-3

  本站资源均收集整理于互联网,其著作权归原作者所有,如有侵犯你的版权,请来信告知,我们将及时下架删除相应资源

Copyright © 2024-2024 EYOUCMS. 易优CMS 版权所有 Powered by EyouCms