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

Самый распространенный способ реализации логики условий — это использование оператора if. В этом отношении он является универсальным, гибким и легким для понимания, что и делает его весьма популярным.

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

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

В этой статье мы рассмотрим четыре альтернативы оператору if: 

  • Тернарный оператор;
  • Оператор switch;
  • Логические операторы (&& и||);
  • Карты сопоставлений.

Тернарный оператор

Он позволяет успешно обрабатывать основные условия формата if-else. В приведенном ниже примере значение, присвоенное message, изменяется в зависимости от выполнения условия hasError.

В классическом виде с оператором if:

let message = "Thanks for contacting us! We'll be in touch shortly!"
if (hasError) {
  message = "Oops, that's an error. Please try again later!"
}

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

const message = hasError
  ? "Oops, that's an error. Please try again later!"
  : "Thanks for contacting us! We'll be in touch!"

В этом случае мы видим несколько преимуществ:

  • Более компактная структура, т.к. message прописывается единожды.
  • Поскольку message более не нуждается в переписывании при возникновении ошибки, мы можем использовать переменную const вместо let.

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

Оператор switch

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

Сначала вариант с if:

if (status === 200) {
  handleSuccess()
} else if (status === 401) {
  handleUnauthorized()
} else if (status === 404) {
  handleNotFound()
} else {
  handleUnknownError()
}

А теперь со switch:

switch (status) {
  case 200:
    handleSuccess()
    break
  case 401:
    handleUnauthorized()
    break
  case 404:
    handleNotFound()
    break
  default:
    handleUnknownError()
    break
}

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

При использовании операторов switch следует также учитывать использование прерываний. В отличие от цепочки if-else, операторы switch могут проскакивать в следующий кейс. Это может внести неясность, поэтому рекомендуется добавление прерывания в конце каждого кейса. 

Логические операторы && и ||

В JavaScript операторы && и || (“и” и “или”) ведут себя не так, как в других языках программирования. Эта особенность поведения и дает возможность применять их в формировании логики выполнения условий. Вот пример работы оператора &&:

  1. Изначально он обращается к левой стороне. Если указанное там значение оказывается false он возвращает это значение, не обращаясь к правой стороне.
  2. Если же значение левой стороны определяется как true, то он возвращает значение, указанное справа.

По схожему принципу работает и оператор ||:

  1. Изначально он анализирует левую сторону. Если ее значение будет true, он вернет это значение, не обращаясь к правой стороне. 
  2. Если же значение слева будет определено как false — вернется значение справа от оператора.

Ключевой вывод из всего описанного в том, что операторы && и || не обязательно возвращают логическое значение, соответствующее true или false. Сначала можно запутаться, но все же потом это может быть весьма полезно. 

Применение оператора &&

Довольно часто возникает необходимость получить доступ к свойству внутри объекта, но нет достаточной уверенности, что данный объект существует.

Например, вы хотите использовать свойство name пользователя для построения приветственного сообщения:

const message = `Welcome, ${user.name}!`

Но что, еслиuser определен как null, false илиundefined?

const message = `Welcome, ${user.name}!`
// TypeError: Cannot read property 'name' of null

Если user не является объектом, а мы все же попробуем обратиться к его свойству name, то JavaScript выдаст ошибку.

Этого можно избежать, добавив в код оператор if:

let message = null
if (user && user.name) {
  message = `Welcome, ${user.name}!`
}

Это сработает, но с помощью оператора && это можно сделать более сжато:

const message = user && user.name && `Welcome, ${user.name}!`

Такой подход позволяет применить к message переменную const вместо let и добиться нужного результата, задействовав всего одну строку кода.

Применение оператора ||

Этот оператор очень удобен для присваивания резервных значений. В качестве примера можно рассмотреть случай, когда вы хотите создать переменную variable для текущего пользователя. Если этот пользователь имеет действующее имя, то оно и должно быть использовано, но если его имя определено как null, то вместо него должно быть использовано резервное значение “Гость”.

Рассмотрим пример с использованием типичного оператора if:

let handle = 'Guest'
if (username) {
  handle = username
}

А теперь вариант с использованием ||:

const handle = username || 'Guest'

И снова мы видим более сжатый код, прописанный всего в одну строку.

Карты сопоставлений

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

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

  • Успех — зеленый
  • Предупреждение — желтый
  • Информация— синий
  • Ошибка — красный

Давайте напишем функцию, которая будет все это выполнять. Сначала вариант с оператором if:

function getStatusColor (status) {
  if (status === 'success') {
    return 'green'
  }
  if (status === 'warning') {
    return 'yellow'
  }
  if (status === 'info') {
    return 'blue'
  }
  if (status === 'error') {
    return 'red'
  }
}

Все здорово, но карта сопоставлений скорее окажется более подходящей. Объектные литералы являются единственным способом реализовать это в JavaScript:

function getStatusColor (status) {
  return {
    success: 'green',
    warning: 'yellow',
    info: 'blue',
    error: 'red'
  }[status]
}

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

Краткое изложение

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

Тернарные операторы идеально подойдут для формирования if-else логики всего в одной строке, но их применение допустимо лишь в достаточно простых случаях. 

Операторы Switch отлично сработают там, где вам потребуется особая переменная, способная принимать различные значения. Эти операторы не имеют такого потенциала, как if, но внешне всегда выглядят лучше.

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

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

Заключение

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

Читайте также:


Перевод статьи Chris Geelhoed: Stop Putting So Many If Statements in Your JavaScript

Предыдущая статьяЗамечательные новые фичи TypeScript 3.5
Следующая статьяЗнакомство с Papermill