От автора: с самого начала JavaScript прошел долгий путь со многими новыми дополнениями и функциями, специально разработанными для того, чтобы сделать язык более удобным и менее многословным. Ниже приведены некоторые недавние добавления в JavaScript, которые я нахожу захватывающими.
Некоторые из этих функций уже доступны в Node, Chrome, Firefox и Safari, в то время как другие все еще находятся на стадии предложения.
Опциональные цепочки
Опциональные цепочки реализуются с помощью оператора «?.». Это прежде всего гарантирует, что предыдущее значение перед знаком вопроса не будет ни неопределенным, ни нулевым. Это действительно полезно при оценке свойств глубоко вложенных объектов.
Необходимо убедиться, что оператор «?.» существует, прежде чем оценивать свойства. Рассмотрим следующий пример:
JavaScript const users = [ { name: «Olagunju Gbolahan», occupation: «Software Developer», sayName(){ console.log(`my name is ${this.name}`); }, address: { office: «New York» } }, { name: «Olawaseyi Moses» }, { name: «Tunde Ednut» }
];
123456789101112 | const users = [ { name: «Olagunju Gbolahan», occupation: «Software Developer», sayName(){ console.log(`my name is ${this.name}`); }, address: { office: «New York» } }, { name: «Olawaseyi Moses» }, { name: «Tunde Ednut» }]; |
Давайте рассмотрим второго пользователя в массиве пользователей:
JavaScript const secondUser = users[1];
1 | const secondUser = users[1]; |
Мы можем захотеть получить адрес офиса этого пользователя. До появления оператора опциональных цепочек нам пришлось бы выполнить относительно неэффективный процесс для получения этой информации:
JavaScript const theAddress = secondUser.address && secondUser.address.office;
console.log(theAddress); // undefined
12 | const theAddress = secondUser.address && secondUser.address.office;console.log(theAddress); // undefined |
Если бы у нас был глубоко вложенный объект, мы должны были бы проверить, существует ли его значение, используя оператор && на каждом уровне. Но с опциональными цепочками мы просто делаем следующее:
JavaScript const theAddress = secondUser?.address?.office;
console.log(theAddress); // undefined
12 | const theAddress = secondUser?.address?.office;console.log(theAddress); // undefined |
Мы также можем использовать это для методов объектов, чтобы проверить их существование перед выполнением:
JavaScript const firstUser = users[0];
console.log(firstUser.sayName?.()); // my name is Olagunju Gbolahan
12 | const firstUser = users[0];console.log(firstUser.sayName?.()); // my name is Olagunju Gbolahan |
Он просто вернется undefined, если метод с данным именем не существует в объекте.
JavaScript console.log(firstUser.sayOccupation?.()); // undefined
1 | console.log(firstUser.sayOccupation?.()); // undefined |
Поскольку оператор опциональных цепочек еще не добавлен в спецификацию JavaScript, он все еще находится на стадии предложения. Вы можете использовать его сегодня с плагином babel-plugin-offer-Additional-Chaining.
Опциональная привязка перехвата
Эта функция пригодится, когда мы заранее знаем, какой будет ошибка, и не хотим вводить избыточные неиспользуемые переменные. Рассмотрим традиционный блок try and catch:
JavaScript try { const parsedJsonData = JSON.parse(obj); } catch (error) { //the variable error has to be declared whether used or unused console.log(obj);
}
123456 | try { const parsedJsonData = JSON.parse(obj);} catch (error) { //the variable error has to be declared whether used or unused console.log(obj);} |
Но с добавлением опциональной привязки перехвата нам не нужно предоставлять неиспользуемые переменные — особенно когда у нас есть значения по умолчанию для блока try.
JavaScript function getName () { let name = «Gbolahan Olagunju»; try { name = obj.details.name } catch {} console.log(name);
}
1234567 | function getName () { let name = «Gbolahan Olagunju»; try { name = obj.details.name } catch {} console.log(name);} |
Оператор конвейера
Это одно из предложенных дополнений к Javascript, и в настоящее время оно находится на стадии 1. Это существенно помогает сделать несколько вызовов функций для одного и того же аргумента доступными для чтения.
Это делается путем передачи значения выражения в качестве аргумента(ов) функции. Попробуйте вызвать следующие функции без оператора конвейера |>.
JavaScript const capitalize = (input) => input[0].toUpperCase() + input.substring(1); const removeSpaces = (input) => input.trim();
const repeat = (input) => `${input}, ${input}`;
123 | const capitalize = (input) => input[0].toUpperCase() + input.substring(1);const removeSpaces = (input) => input.trim();const repeat = (input) => `${input}, ${input}`; |
JavaScript const withoutpipe = repeat(capitalize(removeSpaces(‘ i am gbols ‘)));
console.log(withoutpipe); // I am gbols, I am gbols
12 | const withoutpipe = repeat(capitalize(removeSpaces(‘ i am gbols ‘)));console.log(withoutpipe); // I am gbols, I am gbols |
Но с оператором конвейера читаемость может быть значительно улучшена:
JavaScript const withpipe = ‘ i am gbols ‘ |> removeSpaces |> capitalize |> repeat;
console.log(withpipe); // // I am gbols, I am gbols
12345 | const withpipe = ‘ i am gbols ‘ |> removeSpaces |> capitalize |> repeat;console.log(withpipe); // // I am gbols, I am gbols |
String.trimStart и String.trimEnd
Это формально называлось trimRight и trimLeft, но в ES2019 имена были изменены на псевдонимы trimStart и trimEnd, чтобы сделать их более понятными для пользователей. Рассмотрим следующий пример:
JavaScript let message = » Welcome to LogRocket «; message.trimStart(); // «Welcome to LogRocket »
message.trimEnd(); // «Welcome to LogRocket»;
123 | let message = » Welcome to LogRocket «;message.trimStart(); // «Welcome to LogRocket «message.trimEnd(); // «Welcome to LogRocket»; |
15 советов по производительности приложений React.js
Object.fromEntries
Прежде чем говорить о Object.fromEntries, важно рассмотреть о Object.entries. Метод Object.entries был добавлен в спецификацию ES2017, чтобы обеспечить способ преобразования объекта в эквивалент его массива, предоставляя ему доступ ко всем методам массива для обработки. Рассмотрим следующий объект:
JavaScript const devs = { gbols: 5, andrew: 3, kelani: 10, dafe: 8, }; const arrOfDevs = Object.entries(devs); console.log(arrOfDevs); //[ // [«gbols», 5] // [«andrew», 3] // [«kelani», 10] // [«dafe», 8]
//]
1234567891011121314 | const devs = { gbols: 5, andrew: 3, kelani: 10, dafe: 8,};const arrOfDevs = Object.entries(devs);console.log(arrOfDevs);//[// [«gbols», 5]// [«andrew», 3]// [«kelani», 10]// [«dafe», 8]//] |
Теперь мы можем использовать для массивов метод filter, чтобы получить разработчиков, которые имеют опыт работы более 5 лет:
JavaScript const expDevs = arrOfDevs.filter(([name, yrsOfExp]) => yrsOfExp > 5); console.log(expDevs); //[ // [«kelani», 10] // [«dafe», 8]
//]
123456 | const expDevs = arrOfDevs.filter(([name, yrsOfExp]) => yrsOfExp > 5);console.log(expDevs);//[// [«kelani», 10]// [«dafe», 8]//] |
Теперь возникает проблема: у нас нет простого способа преобразовать результаты обратно в объект. Обычно мы пишем собственный код, чтобы преобразовать его обратно в объект:
JavaScript const expDevsObj = {}; for (let [name, yrsOfExp] of expDevs) { expDevsObj[name] = yrsOfExp; } console.log(expDevsObj); //{ //dafe: 8 //kelani: 10
//}
123456789 | const expDevsObj = {};for (let [name, yrsOfExp] of expDevs) {expDevsObj[name] = yrsOfExp;}console.log(expDevsObj);//{ //dafe: 8 //kelani: 10//} |
Но с введением Object.fromEntries мы можем сделать это одним движением:
JavaScript console.log(Object.fromEntries(expDevs)); //{ //dafe: 8 //kelani: 10
//}
12345 | console.log(Object.fromEntries(expDevs));//{ //dafe: 8 //kelani: 10//} |
flat
Часто у нас есть глубоко вложенные массивы для обработки в результате вызова API. В этом случае особенно важно сгладить массив. Рассмотрим следующий пример:
JavaScript const developers = [ { name: ‘Gbolahan Olagunju’, yrsOfExp: 6, stacks: [‘Javascript’, ‘NodeJs’, [‘ReactJs’, [‘ExpressJs’, ‘PostgresSql’]]] }, { name: ‘Daniel Show’, yrsOfExp: 2, stacks: [‘Ruby’, ‘Jest’, [‘Rails’, [‘JQuery’, ‘MySql’]]] }, { name: ‘Edafe Emunotor’, yrsOfExp: 9, stacks: [‘PHP’, ‘Lumen’, [‘Angular’, ‘NgRx’]] }
];
1234567891011121314151617 | const developers = [ { name: ‘Gbolahan Olagunju’, yrsOfExp: 6, stacks: [‘Javascript’, ‘NodeJs’, [‘ReactJs’, [‘ExpressJs’, ‘PostgresSql’]]] }, { name: ‘Daniel Show’, yrsOfExp: 2, stacks: [‘Ruby’, ‘Jest’, [‘Rails’, [‘JQuery’, ‘MySql’]]] }, { name: ‘Edafe Emunotor’, yrsOfExp: 9, stacks: [‘PHP’, ‘Lumen’, [‘Angular’, ‘NgRx’]] }]; |
JavaScript const allStacks = developers.map(({stacks}) => stacks); console.log(allStacks); // [ // [‘Javascript’, ‘NodeJs’, [‘ReactJs’, [‘ExpressJs’, ‘PostgresSql’]]] // [‘Ruby’, ‘Jest’, [‘Rails’, [‘JQuery’, ‘MySql’]]] // [‘PHP’, ‘Lumen’, [‘Angular’, ‘NgRx’]]
// ]
1234567 | const allStacks = developers.map(({stacks}) => stacks);console.log(allStacks);// [// [‘Javascript’, ‘NodeJs’, [‘ReactJs’, [‘ExpressJs’, ‘PostgresSql’]]]// [‘Ruby’, ‘Jest’, [‘Rails’, [‘JQuery’, ‘MySql’]]]// [‘PHP’, ‘Lumen’, [‘Angular’, ‘NgRx’]]// ] |
Переменная allstacks содержит глубоко вложенные массивы. Чтобы сгладить этот массив, мы можем использовать Array.prototype.flat:
Глубокое погружение в WebSockets
JavaScript const flatSingle = allStacks.flat(); console.log(flatSingle); //[ // «JavaScript», // «NodeJs», // [‘ReactJs’, [‘ExpressJs’, ‘PostgresSql’]]] // «Ruby», // «Jest», // [‘Rails’, [‘JQuery’, ‘MySql’]]] // «PHP», // «Lumen» // [«Angular», «NgRx»]
//]
12345678910111213 | const flatSingle = allStacks.flat();console.log(flatSingle);//[// «JavaScript»,// «NodeJs»,// [‘ReactJs’, [‘ExpressJs’, ‘PostgresSql’]]]// «Ruby»,// «Jest»,// [‘Rails’, [‘JQuery’, ‘MySql’]]]// «PHP»,// «Lumen»// [«Angular», «NgRx»]//] |
Из вышесказанного можно сделать вывод, что массив сглажен на один уровень глубиной, что является аргументом по умолчанию для array.prototype.flat.
Мы можем передать аргумент плоскому методу, чтобы определить степень, до которой мы хотим сгладить массив.
Значение аргумента по умолчанию — 1. Чтобы полностью сгладить массив, мы можем передать аргумент Infinity. Аргумент Infinity сглаживает массив полностью, независимо от его массива:
JavaScript const completelyFlat = allStacks.flat(Infinity); console.log(completelyFlat); //[ // «JavaScript», // «NodeJs», // «ReactJs», // «ExpressJs», // «PostgresSql», // «Ruby», // «Jest», // «Rails», // «JQuery», // «MySql», // «PHP», // «Lumen», // «Angular», // «NgRx»
//]
123456789101112131415161718 | const completelyFlat = allStacks.flat(Infinity);console.log(completelyFlat);//[// «JavaScript»,// «NodeJs»,// «ReactJs»,// «ExpressJs»,// «PostgresSql»,// «Ruby»,// «Jest»,// «Rails»,// «JQuery»,// «MySql»,// «PHP»,// «Lumen»,// «Angular»,// «NgRx»//] |
FlatMap
FlatMap представляет собой комбинацию вызова метода map и метода flat с глубиной 1. Часто это очень полезно, поскольку делает то же самое очень эффективным образом. Ниже приведен простой пример использования map и flatMap:
JavaScript let arr = [‘my name is Gbols’, ‘ ‘, ‘and i am great developer’]; console.log(arr.map(word => word.split(‘ ‘))); //[ // [«my», «name», «is», «Gbols»], // [«», «»], // [«and», «i», «am», «great», «developer»]
//]
1234567 | let arr = [‘my name is Gbols’, ‘ ‘, ‘and i am great developer’]; console.log(arr.map(word => word.split(‘ ‘)));//[// [«my», «name», «is», «Gbols»],// [«», «»],// [«and», «i», «am», «great», «developer»]//] |
JavaScript console.log(arr.flatMap(word => word.split(‘ ‘))); //[ «my» // «name» // «is» // «Gbols» // «» // «» // «and» // «i» // «am» // «great» // «developer»
//]
12345678910111213 | console.log(arr.flatMap(word => word.split(‘ ‘)));//[ «my»// «name»// «is»// «Gbols»// «»// «»// «and»// «i»// «am»// «great»// «developer»//] |
Заключение
В этой статье мы перечислили множество преимуществ новых дополнений к JavaScript. Эти дополнения расширяют возможности разработчика, уменьшая детализацию и повышая удобочитаемость.
Ниже приведено несколько новых функций, которые мы не рассмотрели: JSON.stringify, Sort stability.
Автор: Gbolahan Olagunju
Редакция: Команда webformyself.