Кратко
СкопированоУправляющая конструкция switch позволяет выполнять различные блоки кода, в зависимости от значения переменной.
Похож на if, но решает более узкую задачу.
Как пишется
Скопировано
switch (имя_переменной_значение_которой_сравниваем) { case значение: // код break}
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}
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.
Среди этих задач есть особый подтип — когда нужно посмотреть на значение переменной и выполнить разный код, в зависимости от этого значения. Например, применить разную скидку для клиентов разного статуса — самым любимым клиентам дать скидку 25%, с картой лояльности — 10%, а обычным покупателям не дать ничего.
Такую задачу тоже можно решить с помощью if:
let discountif (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}
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
}
Код выше работает, но выглядит избыточно — в нем очень много сравнений с использованием member. Конструкция switch решает такую задачу меньшим объёмом кода:
let discountswitch (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}
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 вместо 0.
На практике
Скопированосоветует
СкопированоЕсть когнитивное искажение, называемое «Закон инструмента»:
Если из инструментов у вас только молоток, всё вокруг кажется гвоздями
Так и switch часто превращается в такой молоток. Конечно, у switch есть свои преимущества: можно использовать разом несколько case, в условиях можно написать различную логику и прочее.
function greet(role) { switch (role) { case 'admin': case 'moder': return 'Приветствую, смотритель порядка' case 'user': trackUserVisit() return 'Здравствуй, пользователь' case 'guest': return 'Здравствуй, гость' default: return 'Привет, некто' }}
function greet(role) {
switch (role) {
case 'admin':
case 'moder':
return 'Приветствую, смотритель порядка'
case 'user':
trackUserVisit()
return 'Здравствуй, пользователь'
case 'guest':
return 'Здравствуй, гость'
default:
return 'Привет, некто'
}
}
Однако часто нам нужно просто соотнести одно значение с другим. И в таких случаях лучше завести словарь:
const roleToGreeting = { admin: 'Приветствую, босс', moder: 'Приветствую, смотритель порядка', user: 'Здравствуй, пользователь', guest: 'Здравствуй, гость',}const greetings = (role) => roleToGreeting[role] ?? 'Привет, некто'
const roleToGreeting = {
admin: 'Приветствую, босс',
moder: 'Приветствую, смотритель порядка',
user: 'Здравствуй, пользователь',
guest: 'Здравствуй, гость',
}
const greetings = (role) => roleToGreeting[role] ?? 'Привет, некто'
Есть ещё шаблон switch , который якобы сокращает if:
function getCategoryByAge(age) { switch (true) { case (age >= 0 && age <= 12): return "Child" case (age >= 13 && age <= 19): return "Teenager" case (age >= 20 && age <= 35): return "Young Adult" case (age >= 36 && age <= 55): return "Adult" case (age > 55): return "Senior" default: return "Invalid age" }}
function getCategoryByAge(age) {
switch (true) {
case (age >= 0 && age <= 12):
return "Child"
case (age >= 13 && age <= 19):
return "Teenager"
case (age >= 20 && age <= 35):
return "Young Adult"
case (age >= 36 && age <= 55):
return "Adult"
case (age > 55):
return "Senior"
default:
return "Invalid age"
}
}
Использование switch является спорным вопросом и выглядит скорее как хак, нежели задуманный сценарий использования языка. Также учтите, что вашим коллегам эта конструкция может быть непривычна, в отличие от обычных условий, которые понятны всем. Сторонники switch утверждают, что он позволяет сократить код, но пример выше напротив будет более лаконичным без него:
function getCategoryByAge(age) { if (age >= 0 && age <= 12) return "Child" if (age >= 13 && age <= 19) return "Teenager" if (age >= 20 && age <= 35) return "Young Adult" if (age >= 36 && age <= 55) return "Adult" if (age > 55) return "Senior" return "Invalid age"}
function getCategoryByAge(age) {
if (age >= 0 && age <= 12) return "Child"
if (age >= 13 && age <= 19) return "Teenager"
if (age >= 20 && age <= 35) return "Young Adult"
if (age >= 36 && age <= 55) return "Adult"
if (age > 55) return "Senior"
return "Invalid age"
}
советует
Скопировано🛠 Обязательно ставьте break в конце каждого кейса. Такой код будет хорошо читаться и не приведёт к неожиданным багам.
🛠 Всегда добавляйте default блок к своим свитчам. Код приложения постоянно меняется. Когда-нибудь свитч перестанет покрывать все возможные значения переменной и default-случай будет вашей страховкой, которая не даст приложению разломаться.
🛠 Если в вашем свитче меньше трёх кейсов, то if будет читаться проще.
🛠 Если внутри кейса нужно создать переменную, то придётся добавить фигурные скобки, иначе JavaScript упадёт с ошибкой:
switch (variable) { case 5: { const myVar = 'Hello' }}
switch (variable) {
case 5: {
const myVar = 'Hello'
}
}