..
前端岗位内推来了过去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代码是否使用了这样的生成器?
毫无疑问,你在某处遇到过现代的展开语法。
这是一种快速且不可变地克隆数组的天才方法:
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:''}
这就是如何以不可变的方式从对象中移除属性。
当我使用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()
。
说到正则表达式,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(/(?
//->Thec*ts*tonamap
1111111
你知道当VS Code中出现错误时,你可以快速Alt + 点击跳转到错误发生的确切位置吗?
111
VS Code使用捕获组使文件名可点击,从而实现这种快速导航。
我想它大概是这样的:
//Thestupidlylongregex
constregex=/(?
//✅String.raw!
constfilePoint=String.raw`C:\coding-beauty\coding-beauty-javascript\index.js:3:5`;
constextractor=/(?
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
最后我们有了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