company_banner

10 полезных приёмов для JavaScript-программистов

Автор оригинала: Mahdhi Rezvi
  • Перевод
Как всем известно, JavaScript — это язык, который очень быстро развивается. В стандарте ES2020 имеется немало новых возможностей, с которыми вам, вероятно, захочется познакомиться поближе. Честно говоря, писать JS-код можно по-разному. Различные варианты кода, направленные на решение одной и той же задачи, способны дать один и тот же результат, но некоторые из этих вариантов кода могут оказаться значительно короче и чище других. Для того чтобы сделать код качественнее и понятнее, можно пользоваться всяческими полезными приёмами. О некоторых из таких приёмов речь пойдёт в материале, перевод которого мы сегодня публикуем. Надеемся, то, о чём вы сегодня узнаете, когда-нибудь вам пригодится.



1. Проверка наличия обязательных параметров функций


JavaScript позволяет задавать для параметров функций значения, используемые по умолчанию. Зная об этом, мы можем реализовать интересный способ проверки наличия обязательных параметров при вызове функций и методов:

const isRequired = () => { throw new Error('param is required'); };
const print = (num = isRequired()) => { console.log(`printing ${num}`) };
print(2);//printing 2
print()// error
print(null)//printing null

Хорошо сделано, правда?

2. Форматирование JSON-кода


Вы, вполне вероятно, хорошо знакомы с методом JSON.stringify(). А знаете о том, что с помощью этого метода можно форматировать JSON-код? Это, на самом деле, очень просто.

Метод stringify() принимает три параметра. Это — параметры value, replace и space. Два последних параметра в этом списке являются необязательными. Именно поэтому их вы, возможно, раньше не использовали. Для настройки выравнивания JSON-кода необходимо использовать параметр space.

console.log(JSON.stringify({name:"John",Age:23},null,'\t'));
>>> 
{
 "name": "John",
 "Age": 23
}

Вот, кстати, созданный мной React-компонент, в котором использован вышеописанный подход к форматированию JSON-кода. Можете с ним поэкспериментировать.

3. Извлечение из массива уникальных значений


Для того чтобы извлечь из массива уникальные значения, раньше надо было применять метод filter(), с помощью которого отфильтровывались повторяющиеся значения. Теперь же для решения этой задачи мы можем воспользоваться новым стандартным JavaScript-объектом типа Set. Это значительно проще и удобнее, чем фильтрация массива.

let uniqueArray = [...new Set([1, 2, 3, 3,3,"school","school",'ball',false,false,true,true])];
>>> [1, 2, 3, "school", "ball", false, true]

4. Удаление из массива ложных значений


Бывает так, что из массива нужно удалить ложные значения. Это — такие значения, которые в JavaScript приводятся к значению false. В языке существует лишь 6 таких значений (включая само значение false):

  • undefined
  • null
  • NaN
  • 0
  • «» (пустая строка)
  • false

Подобные значения легче всего отфильтровать из массива, воспользовавшись следующей конструкцией:

myArray
    .filter(Boolean);

Если нужно как-то модифицировать исходный массив, а после этого подвергнуть фильтрации новый массив, можно попробовать нечто, напоминающее следующий код:

myArray
    .map(item => {
        // Выполнить изменения и вернуть новый элемент
    })
    .filter(Boolean);

Пользуясь подобной конструкцией, учитывайте то, что исходный массив, myArray, остаётся неизменным.

5. Объединение нескольких объектов в один


У меня было несколько случаев, когда требовалось объединить два или большее количество объектов. В подобных случаях я обычно пользуюсь следующей методикой:

const user = { 
 name: 'John Ludwig', 
 gender: 'Male' 
 };
const college = { 
 primary: 'Mani Primary School', 
 secondary: 'Lass Secondary School' 
 };
const skills = { 
 programming: 'Extreme', 
 swimming: 'Average', 
 sleeping: 'Pro' 
 };
const summary = {...user, ...college, ...skills};

Три точки, использованные в последней строке этого примера, это оператор spread. Подробнее о нём можно почитать здесь.

6. Сортировка числовых массивов


У JavaScript-массивов имеется стандартный метод sort(). Он, по умолчанию, преобразует элементы массива в строки и выполняет лексикографическую сортировку. Это может приводить к проблемам при попытке сортировки числовых массивов. Подобные проблемы, правда, очень просто предотвратить:

[0,10,4,9,123,54,1].sort((a,b) => a-b);
>>> [0, 1, 4, 9, 10, 54, 123]

Методу sort() передаётся функция, выполняющая сравнение двух элементов числового массива. Благодаря этой функции числовой массив можно отсортировать так, как нужно.

7. Отключение действия, выполняемого по щелчку правой кнопки мыши


Возможно, вам понадобится запретить пользователям вашего сайта вызывать контекстные меню элементов щелчком правой кнопки мыши. Хотя это нужно и нечасто, иногда это может оказаться очень кстати.

<body oncontextmenu="return false">
    <div></div>
</body>

Этот простой приём позволяет отключить на странице функционал правой кнопки мыши.

8. Деструктурирующее присваивание с переименованием переменных


Синтаксис деструктурирующего присваивания применяется в JavaScript-выражениях, нацеленных на распаковку элементов массивов или свойств объектов в отдельные переменные. При этом, вместо того, чтобы пользоваться существующими именами свойств объектов, соответствующие переменные можно переименовать:

const object = { number: 10 };
// Извлечение значения свойства number в константу с таким же именем
const { number } = object;
// Извлечение значения свойства number и назначение переменной имени otherNumber
const { number: otherNumber } = object;
console.log(otherNumber); //10

9. Получение элементов из конца массива


Если вам нужно получить элементы, находящиеся в конце массива, можно воспользоваться методом массива slice(), которому передано отрицательное число:

let array = [0, 1, 2, 3, 4, 5, 6, 7] 
console.log(array.slice(-1));
>>>[7]
console.log(array.slice(-2));
>>>[6, 7]
console.log(array.slice(-3));
>>>[5, 6, 7]

10. Ожидание завершения работы всех промисов


Может случиться так, что возникнет нужда в ожидании завершения нескольких промисов. Для того чтобы дождаться выполнения нескольких промисов, можно воспользоваться методом Promise.all(). Главная задача этого метода заключается в ожидании разрешения всех промисов, которые ему передали.

const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.all(PromiseArray)
  .then(data => console.log('all resolved! here are the resolve values:', data))
  .catch(err => console.log('got rejected! reason:', err))

При работе с Promise.all() важно знать о том, что этот метод, если хотя бы один из переданных ему промисов будет отклонён, выбросит ошибку. В результате окажется, что Promise.all() не дождётся завершения работы всех промисов.

Если же вам нужно дождаться завершения работы всех промисов, независимо от того, будут ли они успешно разрешены или отклонены, это значит, что вам стоит прибегнуть к методу Promise.allSettled(). Этот метод имеется в окончательно согласованной версии стандарта ES2020.

const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.allSettled(PromiseArray).then(res =>{
console.log(res);
}).catch(err => console.log(err));
//[
//{status: "fulfilled", value: 100},
//{status: "rejected", reason: null},
//{status: "fulfilled", value: "Data release"},
//{status: "rejected", reason: Error: Something went wrong ...}
//]

Теперь, несмотря на то, что некоторые промисы отклонены, Promise.allSettled() возвращает результаты работы всех промисов.

Знаете какие-нибудь полезные JavaScript-приёмы, которые вы могли бы посоветовать другим программистам?



RUVDS.com
RUVDS – хостинг VDS/VPS серверов

Похожие публикации

Комментарии 27

    +21

    Больше копипасты документации богу копирайтеров!


    Нет, ну честно, иногда у вас стоящие и интересные статьи, а иногда в сотый раз одно и то же. Разве что Promise.allSettled добавили.


    Серьезно, в 2020 году рассказывать про метод .sort у массива.

      0
      Целевая аудитория просто разная. На Хабре ведь не только профи, но и начинающие гуляют. Я и нашёл для себя нашёл полезные моменты.
        +1
        Или забрасываемые в эти джунгли раз в месяц(=
          +2

          Я бы не хотел работать с человеком, который изучает JS по статьям такого качества и настолько разбросанным по тематике. Одно дело когда что-то новенькое или спорное всплывает, вроде недавних immutable set'ов и объектов. Но нет, в этой статье рассказывают ни о чём, да ещё и без нормального объяснения.


          Если человек хочет научиться писать на JS, пусть идёт на learn.javascript.ru. Там и контент качественнее и хоть какая-то систематизация информации. А такие вот статьи — просто бред сивой кобылы. Они новичкам только вредить могут, а профи от них только бесятся. Бессмысленная трата времени и читающих, и пишущего.

            –1
            А мне интересно, насколько хороший программист тот человек, который делает вывод о том, что изучает другой человек исходя из одного комментария. Так ведь можно и в работе прийти к выводу «вы знаете лучше заказчика, что нужно заказчику».

            Я изучаю JS через интерактивные курсы htmlacademy (знакомиться с языком лучше там — пройдено), через learn.javascript.ru, через CodeWars. А интересные статьи на Хабре, например, как эта, иногда неплохо дополняют тот же learn.javascript.ru. Главное — выбирать только нужные кусочки и отсеивать всё лишнее.

            И я понимаю, что даже через 2-3 года нельзя зазнаваться и пропускать «новичковые материалы» — это способ избежать «зашоренности» и механического подхода к программированию. Мало ли, вдруг что-то важное пропустил и забыл, или новичок изобрёл новый полезный трюк, просто потому, что не знал, что «это невозможно».
              –1
              человек, который делает вывод о том, что изучает другой человек исходя из одного комментария

              Если вы спроецировали мой комментарий на себя лично, уж простите, но я не к вам обращался, а вообще к людям которые приходят в веб из вот этих статей, думая что наберут вот таких вот pro tips и станут хорошими программистами. А таких к сожалению много, и их шлейф тянется со времен jquery.


              И я понимаю, что даже через 2-3 года нельзя зазнаваться и пропускать «новичковые материалы» — это способ избежать «зашоренности»

              Держать руку на пульсе совершенно не значит смотреть материалы для новичков. Наоборот, это следить за пропоузалами, смотреть документацию и примеры реального использования новых фич. С обсуждением и осознанием плюсов или минусов определенных фич.


              Например при выходе es6 сразу можно было заметить, что часть людей побежали использовать везде промисы, а часть продолжала сидеть себе спокойно на bluebird — консистентность кода важнее хайповых фичей.


              Новичок отличается от «зашоренного» профи тем, что не способен сказать почему конкретно он не будет использовать ту или иную фичу. Новичок будет смотреть на новый синтаксис и обтекать слюнями, а профи посмотрит и скажет, что не будет его использовать, потому что в случае чего явисты из соседнего отдела не смогут поправить в коде что-то во время отпуска этого самого профи.


              новичок изобрёл новый полезный трюк, просто потому, что не знал, что «это невозможно».

              А трюкачества все никому не нужны. Потому что они никому кроме самого трюкача не понятны, и в случае чего даже сам трюкач может не вспомнить зачем он это делал.

            +1
            Не все эти моменты нужны «начинающим», особенно «деструктирующее присваивание», термин-то какой…

            Не упомянули про то, что splice модифицирует массив оригинал, или что Вы подразумевали под «получить последние элементы массива»?

            Да и использование «new Set» просто для получения уникальных записей в боооольшом массиве — может привести к необоснованной трате ресурсов.

            Просто если уж советы «новичкам», то как-то поразвёрнутее бы…
              0
              Деструктурирующее же.
          +6
          Пункт 4, неужели никто никогда не вспоминает про reduce, зачем вы делаете два прохода, производя 2 массива, если можно всё это сделать в одну итерацию с какими-то явными проверками.

          Зачем упоминать про ES2020, если тут нет практически ни одной фичи из последних реализаций, например nullish или pipe. Очередная копипаста 100500 подобных статей ради плюсов, без практической пользы для сообщества.
            0

            Насчёт 4 пункта вы одновременно и правы, и нет. Можно сделать всё в один прогон с помощью reduce.


            Кто не знает, это делается примерно вот так:


            myArray.reduce((acc, current) => {
                if (!Boolean(current)) {
                    return;
                }
                // ...
                return acc.push(current);
            }, []);

            Можно сделать так, но зачем? Это требует больше времени, чтобы понять, что происходит. А оптимизирует примерно ничего.


            Не важно сколько прогонов 1, 2 или 1000. On = 2On. Сложность алгоритма не увеличивается, а константы мы не считаем.


            К тому же пункт всё-таки был не про это, а про filter(Boolean).

              –1

              Конечно же, в строке


              return acc.push(current);

              должно быть, на самом деле,


              return [...acc, current];
                0

                Зачем на каждой итерации создавать новый массив, посмотрите какая у вас сложность алгоритма выходит? Делайте просто acc.push(); return acc;

                  +1

                  Тоже верно. У меня просто уже иммутабельность головного мозга)

              –2
              Пункт 4, неужели никто никогда не вспоминает про reduce, зачем вы делаете два прохода, производя 2 массива, если можно всё это сделать в одну итерацию с какими-то явными проверками.
              Да можно flatmap, если вы стильный, модный, молодёжный.
                0
                В более толковых языках map и filter будут возвращать не сконструированные массивы, а что-то вроде view/итераторов, поэтому замена map+filter на reduce производительности особо прибавлять не будет, а читабельность уменьшит.

                В JavaScript это, конечно же, не так. Но я всё равно не считаю нужным заменять map+filter на reduce, даже в JavaScript — за исключением случаев, когда производительность крайне важна, конечно же. Просто по принципу «та мне проще вам штраф заплатить, чем руку сбивать».
                +16
                В стандарте ES2020 имеется немало новых возможностей, с которыми вам, вероятно, захочется познакомиться поближе.

                Но не в рамках этой статьи.

                  +1

                  Чуть ли не всё это есть в книге "ES6 и не только"

                    +2
                    пробежал по диагонали. читается не слишком легко. какой процент людей поймёт такое определение:
                    Полизаполнения (polyfills), которые также
                    называют библиотеками Shim, представляют собой шаблоны для
                    определения поведений из новой среды для более старых сред.
                      0
                      Не помню, как именно написана книга, но полагаю, после определения идут пояснения и примеры. Мне книга помогла понять нововведения ES6, в котором я тогда не ориентировался.
                    +10
                    О, в этом месяце ещё не было.
                      +23
                      Этот простой приём позволяет отключить на странице функционал правой кнопки мыши.
                      <body oncontextmenu="return false">


                      11. Этот простой приём позволяет залить фон страницы красным цветом.
                      <body bgcolor="red">


                      надеюсь, получилось не слишком тонко?
                        +1
                        У меня такое ощущение, что точно такую же статью я читал тут в прошлом году. Ну, может пару пунктов поменялось.
                          +2
                          Уберите пункт про контекстное меню, ну правда же. Им начинают пользоваться ради «защиты от копирования» и когда тебе правда нужно контекстное меню — его нет, бесит жутко.
                            0
                            Этот пункт обходится нажатием Shift с правым кликом.
                            –1
                            .
                              0
                              Подборка малость сумбурна.

                              1. Сделано-то хорошо, но узко. Иронично то, что обязательный параметр num может быть null. Обязательный, но не слишком. Фактически это не isRequired, а isDefined. Для обязательных по-прежнему нужен != null. Для опциональных — arguments.length и rest.length.

                              2. Быстрый рецепт:

                              console.log(JSON.stringify(obj, 0, 2));

                              7. Со стороны разработчика: повесить на window, а еще лучше — ничего. Со стороны пользователя, в зависимости от контекста: Ctrl+Alt+C, или Allow Right-Click, или Ctrl+F4.

                              10. Promise.allSettled
                                0
                                Это все для новичков.

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое