色五月,
往时10年里,JavaScript赢得了长足跳跃,每年齐有全新的功能升级。
今天,咱们来望望早期ES9中引入的5个最鬈曲的特质,望望你是否错过了其中一些。
1. 异步生成器和迭代
异步生成器是ES9中一个纷乱的特质。
就像平淡的生成器,但咫尺它不错在异步职责(如蚁集肯求)后弹出值:
function* asyncGenerator { yield new Promise((resolve) => setTimeout( => resolve('done this '), 2000) ); yield new Promise((resolve) => setTimeout( => resolve('done that '), 3000) );}
当咱们调用.next时,咱们会得到一个Promise:
const asyncGen = asyncGenerator;asyncGen.next.value.then(console.log);asyncGen.next.value.then(console.log);
这是一个纷乱的用具,不错在web期骗中以结构化+可读的神气流式传输数据 — 望望这个为同样YouTube的视频共享期骗缓冲和流式传输数据的函数:
async function* streamVideo({ id }) { let endOfVideo = false; const downloadChunk = async (sizeInBytes) => { const response = await fetch( `api.example.com/videos/${id}` ); const { chunk, done } = await response.json; if (done) endOfVideo = true; return chunk; }; while (!endOfVideo) { const bufferSize = 500 * 1024 * 1024; yield await downloadChunk(bufferSize); }}
咫尺要破费这个生成器,咱们将使用for await of — 异步迭代:
for await (const chunk of streamVideo({ id: 2341 })) { // process video chunk}
我想知谈本体的YouTube JavaScript代码是否使用了这么的生成器?
2.对象的剩余/伸开运算符
毫无疑问,你在某处碰到过当代的伸开语法。
这是一种快速且不成变地克隆数组的天才表率:
const colors = ['', '', ''];console.log([...colors, '']); // ['', '', '', '']
在ES6之前咱们从未有过它,咫尺它无处不在。
Redux等于一个鬈曲的例子:
export default function userState(state = initialUserState, action) { console.log(arr); switch (action.type) { case ADD_ITEM: return { ...state, arr: [...state.arr, action.newItem] }; default: return state; }}
从ES9启动,它也适用于对象:
const info = { name: 'Coding Beauty', site: 'codingbeautydev.com',};console.log({ ...info, theme: '' });/* Output:{ name: 'Coding Beauty', site: 'codingbeautydev.com', theme: ''}*/
消失属性:
const langs = { j: 'java', c: 'c++',};console.log({ ...langs, j: 'javascript' });// Output: { j: 'javascript', c: 'c++' }
这使得它超越符合在默许值的基础上构建,尤其是在制作人人实用表率时。
或者像我用Material UI定制默许主题那样:
使用伸开语法,你甚而不错去掉不想在副本中出现的对象属性。
const colors = { yellow: '', blue: '', red: '',};const { yellow, ...withoutYellow } = colors;console.log(withoutYellow);// Output: { blue: '', red: '' }
这等于何如以不成变的神气从对象中移除属性。
3. String.raw
当我使用String.raw时,我是在说:只给我我给你的东西。不要处理任何东西。不要动那些转义字符:
不再需要转义反斜杠,咱们无谓写:
const filePath = 'C:\\Code\\JavaScript\\tests\\index.js';console.log(`The file path is ${filePath}`);// Output: The file path is C:\Code\JavaScript\tests\index.js
而是写:
const filePath = String.raw`C:\Code\JavaScript\tests\index.js`;console.log(`The file path is ${filePath}`);// Output: The file path is C:\Code\JavaScript\tests\index.js
相称符合编写带有渊博这些反斜杠的正则抒发式:
像这么但更糟:
从这个 :
const patternString = 'The (\\w+) is (\\d+)';const pattern = new RegExp(patternString);const message = 'The number is 100';console.log(pattern.exec(message));// ['The number is 100', 'number', '100']
到这个 :
const patternString = String.raw`The (\w+) is (\d+)`;const pattern = new RegExp(patternString);const message = 'The number is 100';console.log(pattern.exec(message));// ['The number is 100', 'number', '100']
是以"raw"意味着未处理的。
这等于为什么咱们有String.raw但莫得String.cooked。
4. 复杂的正则抒发式特质
说到正则抒发式,ES9并莫得让东谈主失望。
它整个装载了开头进的正则抒发式特质,用于高档字符串搜索和替换。
向后查找断言
这是一个新特质,用于确保只好某个特定阵势出咫尺你要搜索的内容之前:
正向后查找:白名单 ?
负向后查找:黑名单 ?
const str = "It's just $5, and I have €20 and £50";// Only match number sequence if $ comes firstconst regexPos = /(?
定名拿获组
拿获组一直是正则抒发式中最认简直特质之一,用于以复杂的神气调遣字符串。
const str = 'The cat sat on a map';// $1 -> [a-z]// $2 -> a// $3 -> t// indicates groupstr.replace(/([a-z])(a)(t)/g, '$1*$3');// -> The c*t s*t on a map
频频,这些组按照它们在正则抒发式中的相对位置定名:1, 2, 3...
但这使得贯穿和革新那些愚蠢的长正则抒发式变得愈加困难。
是以ES9通过?来定名拿获组处治了这个问题:
const str = 'The cat sat on a map';// left & rightconsole.log(str.replace(/(?[a-z])(a)(?t)/g, '$*$'));// -> The c*t s*t on a map
你知谈当VS Code中出现乖谬时,你不错快速Alt + 点击跳转到乖谬发生的真确位置吗?
VS Code使用拿获组使文献名可点击,从而齐备这种快速导航。
幼女白丝我想它大略是这么的:
// The stupidly long regexconst regex = /(?
5. Promise.finally
临了咱们有了Promise.finally 。
你知谈finally老是会运行一些代码,无论是否有乖谬吗?
function startBodyBuilding { if (Math.random > 0.5) { throw new Error("I'm tired"); } console.log('Off to the gym ️♂️');}try { startBodyBuilding;} catch { console.log('Stopped excuse');} finally { console.log("I'm going!♂️");}
是以Promise.finally就像那样,关联词用于异步任务:
async function startBodyBuilding { await think; if (Math.random > 0.5) { throw new Error("I'm tired"); } console.log('Off to the gym ️♂️');}startBodyBuilding .then( => { console.log('Started '); }) .catch( => { console.log('No excuses'); }) .finally( => { console.log("I'm going!♂️"); });
Promise.finally最大的优点是当你鸠合好多Promise时:
它也能很好地与Promise链一谈职责:
getFruitApiUrl.then((url) => { return fetch(url) .then((res) => res.json) .then((data) => { fruits.push(data); }) .catch((err) => { console.error(err); }) .finally( => { console.log(fruits); });});
这是由ES9带来的。
临了的想考
ES9记号着JavaScript的一个要紧飞跃色五月,,引入了几个对当代建造至关鬈曲的特质。使你能够快速编写更明晰、更粗略、更富默契力的代码。