Кратко о тернарных операторах
Тернарный оператор работает с тремя операндами: одним условием и двумя выражениями. Возвращает первое выражение, если условие истинно и второе, если условие ложно.
Используется как компактная замена условного оператора if...else
.
Пример
const num = 5 console.log(num === 5 ? 'Пять' : 'Не пять') // Пять
Как пишется
(A) ? (B) : (C)
Где A — условие, B — первое выражение, C — второе выражение.
Если первый операнд A вычисляется в истинное выражение true
, то оператор вернёт выражение B. Если в false
— вернёт выражение C.
Как понять
По механике работы тернарный оператор похож на инструкцию if...else
, но позволяет писать меньше кода и записывать результат работы сразу в переменную.
В качестве примера преобразуем код, который использует инструкцию if...else
:
const num = 10
let result if (num > 10) {
result = 'Число больше 10'
} else {
result = 'Число меньше или равно 10'
}
console.log(result)`
Заменим условную конструкцию тернарным оператором:
const num = 10
const result = num > 10 ? 'Число больше 10' : 'Число меньше или равно 10'
console.log(result)`
Код сократился и стал устанавливать значение переменной num
сразу при объявлении. Это позволило использовать const
вместо let
.
Тернарный оператор как выражение
Тернарный оператор возвращает результат, его можно записать в переменную, как в примере выше, или вернуть с помощью return
из функции:
const salutation = function(name) {
return name ? `Рад видеть, ${name}!` : 'Привет, друг!'
}
console.log(salutation('Дока Дог')) // 'Рад видеть, Дока Дог!
console.log(salutation()) // 'Привет, друг!'``
Так как результат работы тернарного оператора можно записать в переменную, то смело делаем вывод, тернарный оператор — выражение.
Подробнее о разнице между выражениями и инструкциями читайте в отдельной статье.
Вложенные тернарные операторы
Внутри одного тернарного оператора можно написать другой:
const num = 10
const result = num > 10 ? 'Число больше 10' :
num === 10 ? 'Число равно 10' : 'Число меньше 10'
console.log(result) // 'Число равно 10'`
В этом случае запись идентична использованию конструкций if...else if ... else
. Сначала проверяется первое условие, если оно ложно, то проверяется второе и так далее. Отступы в примере проставлены для лучшей читаемости конструкции, они не влияют на выполнение кода.
На практике
При выборе между if...else
и тернарным оператором в приоритет нужно ставить читабельность. Код читается чаще, чем пишется, поэтому чем лучше код читается, тем легче его понимать и изменять.
Разберём выбор между тернарным оператором и if...else
на примерах.
Допустим, нужно по-разному поприветствовать нового и уже зарегистрированного пользователя. Здесь удобно использовать тернарный оператор, так как проверка короткая:
const greetings = function(isRegistered, userName) {
return isRegistered ? `Привет, ${userName}!` : 'Привет, незнакомец'
}
Когда появляются вложенные тернарные операторы, лучше переходить на if...else
. Сравните код с тернарным оператором:
const greetings = function(isRegistered, userName, bePolite) {
return isRegistered ? `Привет, ${userName}!` : bePolite ? 'Здравствуйте!' : 'Привет, незнакомец' }``
И код с if...else
:
const greetings = function(isRegistered, userName, bePolite) {
if (isRegistered) {
return `Привет, ${userName}!`
} else if (bePolite) {
return 'Здравствуйте!'
} else {
return 'Привет, незнакомец'
}
}
Если же приветствие зависит от роли, то цепочки вложенных тернарных операторов становятся нечитаемыми:
const greetings = function(role) {
return result = role === 'admin' ? 'Приветствую, босс' : role === 'moder' ? 'Приветствую, смотритель порядка' : role === 'user' ? 'Здравствуй, пользователь' : role === 'guest' ? 'Здравствуй, гость' : 'Привет, некто'
}
Такой код можно улучшить форматированием, но лучше использовать switch
:
const greetings = function(role) {
switch (role) {
case 'admin':
return 'Приветствую, босс'
case 'moder':
return 'Приветствую, смотритель порядка'
case 'user':
return 'Здравствуй, пользователь'
case 'guest':
return 'Здравствуй, гость'
default:
return 'Привет, некто'
}
}
На собеседовании
Что значит слово «тернарный»?
Кратко о SwitchCase
Кратко
Управляющая конструкция switch
позволяет выполнять различные блоки кода, в зависимости от значения переменной.
Похож на if...else
, но решает более узкую задачу.
Как пишется
switch (имя_переменной_значение_которой_сравниваем) {
case значение: // код break }`
В круглых скобках указывается переменная, значение которой сравнивается. В фигурных скобках с помощью ключевого слова case
указываются возможные значения и код, который нужно выполнить.
Пример приветствия пользователя в зависимости от статуса:
switch (membershipStatus) {
case 'vip':
// выполнится, если в переменной membershipStatus хранится строка 'vip'
console.log('Приветствуем вас, ваше великолепие!')
console.log('рады вас видеть!')
break
case 'diamond':
console.log('Здравствуйте, бриллиантовый клиент!')
break
case 'gold':
console.log('Привет, золотой мой!')
break
default:
// выполнится, если ни один другой случай не сработал
console.log('Прив')
break }`
Как понять
В программировании часто встречается задача выполнения разного кода в зависимости от какого-либо условия. Обычно, такие задачи решают с помощью конструкции if...else
.
Среди этих задач есть особый подтип — когда нужно посмотреть на значение переменной и выполнить разный код, в зависимости от этого значения. Например, применить разную скидку для клиентов разного статуса — самым любимым клиентам дать скидку 25%, с картой лояльности — 10%, а обычным покупателям не дать ничего.
Такую задачу тоже можно решить с помощью if..else
:
let discount
if (memberStatus === 'vip') {
discount = 0.25
} else if (memberStatus === 'diamond') {
discount = 0.2
} else if (memberStatus === 'gold' || memberStatus === 'silver') {
// скидка 10% пользователям статуса золотой и серебряный
discount = 0.1
} else {
discount = 0 }`
Код выше работает, но выглядит избыточно — в нем очень много сравнений с использованием memberStatus
. Конструкция switch
решает такую задачу меньшим объёмом кода:
let discount
switch (memberStatus) {
case 'vip':
discount = 0.25
break
case 'diamond':
discount = 0.2
break case 'gold':
case 'silver':
// можно написать несколько кейсов и связать с одним блоком
discount = 0.1
break
default:
discount = 0
break }`
В круглых скобках указана переменная, значение которой нужно сравнивать с различными возможными значениями — кейсами. Порядок обычно не имеет значения.
Внутри кейса пишется список команд, которые нужно выполнить. Список команд завершается оператором break
.
Существует необязательный кейс default
, который срабатывает, если ни одно значение не подошло.
Что будет, если не поставить break
?
Если вы забыли поставить break
, то будут выполнены все команды, начиная со сработавшего кейса и до тех пор, пока либо не встретится break
, либо не закончится switch
.
Сравните:
Выполняется весь код от текущего case
до следующего break
, даже если он вне текущего кейса.
В коде появился баг — значение для бриллиантового уровня будет установлено в 0.1
вместо 0.2
.
На практике
🛠 Обязательно ставьте break
в конце каждого кейса. Такой код будет хорошо читаться и не приведёт к неожиданным багам.
🛠 Всегда добавляйте default
блок к своим свитчам. Код приложения постоянно меняется. Когда-нибудь свитч перестанет покрывать все возможные значения переменной и default
-случай будет вашей страховкой, которая не даст приложению разломаться.
🛠 Если в вашем свитче меньше трёх кейсов, то if...else
будет читаться проще.
🛠 Если внутри кейса нужно создать переменную, то придётся добавить фигурные скобки, иначе JavaScript упадёт с ошибкой:
switch (variable) {
case 5: {
const myVar = 'Hello' } }`