Хороший разработчик всегда должен учиться чему-то новому и совершенствовать навыки, которые у него уже есть. Поэтому сейчас мы будем учиться писать более чистый и понятный код!
Ниже вы найдете большую подборку кратких вариантов широко распространенных конструкций. Во многих случаях они не только позволяют кодить быстрее, но и выглядят понятнее и чище, чем длинные аналоги.
В конце статьи приведен список современных возможностей языка, разделенный на версии.
Объявление переменных и присваивание значений
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:
Важно: не злоупотребляйте стрелочными функциями из-за их краткости, используйте их по прямому назначению, например, для сохранения контекста выполнения.
Сокращения в программировании похожи на лекарства. В небольших дозах они полезны и делают вашу жизнь лучше, но при передозировке возможно отравление и другие неприятные побочные эффекты.
Поэтому соблюдайте меру и используйте сокращения только тогда, когда они действительно нужны и не нарушают читаемость кода.