33 приема оптимизации JavaScript, которые вы должны знать в 2021 году

33 приема оптимизации JavaScript, которые вы должны знать в 2021 году

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

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

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

Объявление переменных и присваивание значений

1. Объявление нескольких переменных

Переменные можно объявлять через запятую, при этом не требуется повторно использовать инструкцию let :

Такой подход особенно удобен при объявлении нескольких переменных без моментального присваивания значений:

2. Арифметические операции

Присваивание в JavaScript легко совмещается с арифметическими операторами:

3. Присваивание значений нескольким переменным

Если требуется присвоить значения сразу нескольким переменным, мы обычно делаем так:

Но всю эту логику можно свести в одну строку, если использовать деструктуризацию:

Синтаксис деструктуризации работает не только с массивами, но и с обычными объектами:

4. Присваивание со значением по умолчанию

Иногда требуется положить в переменную какое-то значение, предварительно убедившись, что это значение существует и не является falsy ( null , undefined , пустая строка, 0).

Для этого можно использовать обычную конструкцию if-else :

Можно написать короче.

Взять, например, логический оператор || . Если в переменной находится truthy-значение, то будет возвращено оно, иначе – дефолтное значение с правой стороны оператора.

Еще более современный подход – nullish coalescing operator – ?? . Однако он проверяет не на все falsy-значения, а только на null и undefined . В остальном логика такая же, как у оператора || .

Условия

5. Автоматическая проверка на truthy и falsy значения

Иногда требуется проверить, есть ли в переменной какое-либо значение. При этом важно учитывать и null , и undefined , и другие falsy-значения ( NaN , пустая строка, 0).

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

Можно просто положиться на JavaScript и его динамическую конверсию типов.

Оператор if самостоятельно приведет переменную к логическому значению и осуществит проверку.

6. Логические операторы вместо if

В пункте Присваивание с дефолтным значением мы уже видели, как логический оператор ( || ) может заменить конструкцию if .

Оператор && также способен на многое:

Если test1 является falsy-значением, то до инструкции callMethod() выполнение не дойдет.

7. Тернарный оператор вместо if

Зачастую простые конструкции if-else можно заменить еще более простым тернарным оператором:

Таким образом можно преобразовать и более сложные условия, даже вложенные:

Важно: чем сложнее условие, тем запутаннее выглядит тернарный оператор и предпочтительнее – стандартная конструкция if-else .

8. Проверка на значение из набора

Если требуется выполнить какие-то действия, когда x равен одному из нескольких значений, первым порывом может быть использование обычных сравнений:

Но чем больше таких «подходящих» значений, тем сильнее разрастается условие и тем проще сделать ошибку. Проще поместить все эти значения в массив и использовать метод Array.prototype.includes для проверки:

Важно: метод includes использует строгое сравнение с учетом типа аргумента.

9. Коллекция вместо switch

Вместо того, чтобы рассматривать каждый случай внутри инструкции switch , можно добавить их все в объект:

Циклы

10. Короткий синтаксис for

Всем знакомый старый-добрый цикл for имеет довольно громоздкую структуру:

К счастью, в последних версиях языка появилось несколько более удобных альтернатив:

Кроме того, есть замечательный функциональный метод forEach :

Такой код выглядит очень понятно, но у него есть некоторые ограничения. Например, перебор массива методом forEach нельзя прервать с помощью инструкции break .

Числа

11. Конверсия строки в число

Одиночный оператор сложения ( + ) неявно приводит тип полученного аргумента к числу.

12. Экспоненциальная запись

Избавиться от большого количества нулей поможет экспоненциальная запись:

13. Возведение в степень

Если вы вдруг до сих пор не знали, то пришло время узнать – в JavaScript есть специальный оператор для возведения в степень:

14. Округление

Двойное побитовое отрицание для 32-битных целых чисел дает такой же эффект, как Math.floor (округляет вниз):

Строки

15. Получение символа из строки

Строка – это по сути массив символов, поэтому к каждому из них можно обратиться по индексу:

16. Повторение строки

Чтобы соединить несколько одинаковых строк в одну, существует несколько подходов. Самый очевидный – и самый громоздкий – использовать цикл:

Но есть и более логичный – встроенный метод String.prototype.repeat() :

Бонус для любителей нестандартных решений:

17. Конкатенация

Составление одной строки из нескольких фрагментов – ужасная головная боль. Нас спасут шаблонные литералы:

Они не только позволяют избежать многочисленных конкатенаций, но и поддерживают многострочность.

Массивы

18. Наличие элемента

Обычно чтобы проверить, присутствует ли элемент в массиве, мы используем метод indexOf и сравниваем найденный индекс с -1 .

Но можно использовать другой подход, без сравнения индексов – побитовый оператор

возвращает 0 только для значения -1 . Для всех других значений будет возвращено число, отличное от нуля, то есть truthy-значение.

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

Не стоит забывать и про удобнейший метод Array.prototype.includes :

19. Поиск элемента

Метод Array.prototype.find – это удобная функциональная замена простому перебору элементов массива с помощью цикла for :

20. Spread-синтаксис

Spread-синтаксис был введен в язык специально для облегчения множества операций со сложными структурами данных.

Например, для конкатенации массивов:

Или клонирования массива:

21. Минимальное и максимальное значение

Методы Math.max и Math.min могут принимать любое количество аргументов. Чтобы передать им массив, можно использовать метод Function.prototype.apply :

А можно воспользоваться деструктуризацией:

Объекты

22. Присваивание значений

Если имя свойства совпадает с именем переменной, в которой хранится значение, дублировать его необязательно:

23. Перебор ключей и значений

В современном JavaScript есть сразу 3 метода для перебора объектов: Object.keys() , Object.values() и Object.entries() . Каждый из них возвращает массив – ключей, значений или сразу и того, и другого.

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

Функции

24. Параметры по умолчанию

Современный стандарт JavaScript позволяет задать дефолтные значения параметров прямо в сигнатуре функции. Теперь не нужно проверять это отдельно:

Важно: дефолтное значение устанавливается только в том случае, если указанный параметр не передан или равен undefined . На null это не распространяется.

25. Операции в return

В операторе return можно производить разнообразные вычисления, что позволит сэкономить пару строк кода.

26. Стрелочные функции

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

Стрелочные функции позволяют возвращать значение неявно, без использования оператора return:

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

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

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