JavaScript Switch Get Certified
The switch statement is an alternative to writing
long chains of if...else if statements. It compares
one value against several possible cases and runs the matching
block of code.
A switch statement is often easier to read than a
long if...else if chain when you are checking the
same value against many possible options.
In this lesson, you will learn the syntax of switch,
how break and fall-through behave, and when to
prefer switch over if...else.
Basic switch Syntax
A switch statement evaluates an expression once and
compares its value against each case using strict
equality (===).
What this code does: A switch compares one value against several cases.
Because day is Tuesday, that case runs and prints its message, then break stops further checks.
let day = "Tuesday";
switch (day) {
case "Monday":
console.log("Start of the work week.");
break;
case "Tuesday":
console.log("Second day of the week.");
break;
default:
console.log("Some other day.");
}
let day = "Tuesday"; stores the string "Tuesday" in the variable day. This is the value the switch statement will compare against each case.switch (day) { begins the statement. The expression in parentheses, day, is evaluated once, and its value ("Tuesday") is then compared with each case label below, from top to bottom, using strict equality (===). The opening brace starts the block that holds all the cases.case "Monday": is the first label. JavaScript checks "Tuesday" === "Monday", which is false, so it skips the code that belongs to this case and moves to the next label."Start of the work week." but it only runs when the value matches "Monday". It is skipped.break would end the switch after the Monday code. It is never reached, because the Monday case did not match.case "Tuesday": is checked next. "Tuesday" === "Tuesday" is true, so there is a match. JavaScript jumps into the switch block at this point and starts running the code below the label."Second day of the week.". This is the output of the program.break; immediately leaves the switch block. Without it, execution would continue into the default code below. With it, the statement stops here.default: marks the code to run when no case matched. Since "Tuesday" matched, and break already ended the switch, this label is never used here."Some other day." for any day that is not Monday or Tuesday. It is skipped here.} ends the switch block. The output of the whole program is Second day of the week.The break Keyword
The break statement stops the switch
from continuing to check the remaining cases. Without it,
execution “falls through” into the next case.
What this code does: Each case is checked with strict equality.
fruit is banana, so that case’s message is printed. break prevents fall-through to later cases.
let fruit = "banana";
switch (fruit) {
case "apple":
console.log("Apples are red or green.");
break;
case "banana":
console.log("Bananas are yellow.");
break;
case "grape":
console.log("Grapes are small and round.");
break;
default:
console.log("Unknown fruit.");
}
let fruit = "banana"; stores the string "banana". This is the value that will be compared with every case.switch (fruit) { evaluates fruit once and compares the result with each case using strict equality (===), checking them in order from top to bottom.case "apple": is checked first. "banana" === "apple" is false, so JavaScript moves on to the next case."Apples are red or green.". It is skipped because the apple case did not match.break belongs to the apple case. It is never reached here.case "banana": is checked next. "banana" === "banana" is true, so this is the matching case and JavaScript starts running its code."Bananas are yellow.". This is the output of the program.break; exits the switch right away, so the grape case and the default code are not executed. This is what stops fall-through.case "grape": would be checked next, but because break already ended the switch, JavaScript never gets here."Grapes are small and round." if the fruit were "grape".break would end the switch after the grape code.default: is the fallback. It runs only when no case matches the value, for example if fruit were "mango"."Unknown fruit." for any fruit that is not listed. It is skipped because banana matched.} ends the switch. The output is Bananas are yellow.Fall-Through Behavior
If you forget break, JavaScript continues executing
the code in the next case, even if its condition doesn’t match.
This is called “fall-through.”
What this code does: Without break, execution “falls through” into the next cases.
Matching banana also runs the grape and default messages. Always use break unless fall-through is intentional.
let fruit = "banana";
switch (fruit) {
case "apple":
console.log("Apples are red or green.");
case "banana":
console.log("Bananas are yellow.");
case "grape":
console.log("Grapes are small and round.");
default:
console.log("Unknown fruit.");
}
let fruit = "banana"; stores "banana". It is the same value as in the previous example, but this time the break statements have been removed, so the result is very different.switch (fruit) { evaluates fruit once and starts comparing it with the case labels using strict equality.case "apple": does not match, because "banana" === "apple" is false. JavaScript moves on to the next label.break either, which would matter if it had matched.case "banana": matches, so JavaScript begins executing from this point. From now on it will keep running line after line until it meets a break or the end of the switch."Bananas are yellow.". There is no break after it, so execution does not stop here.case "grape": is only a label. When execution falls through, JavaScript does not check this condition again. It just continues into the code below, even though the fruit is not a grape."Grapes are small and round.", even though the value is "banana". This is the unwanted fall-through caused by the missing break.default: is also just a label here. Execution flows straight past it, because nothing stopped it earlier."Unknown fruit.", which is wrong and confusing, since the fruit is a known one.} ends the switch. Three lines are printed: Bananas are yellow., Grapes are small and round. and Unknown fruit. Try adding a break; after each console.log in the editor to fix this.
Notice that once "banana" matches, every case after
it also runs because there is no break to stop
execution.
Intentional Fall-Through
Fall-through isn’t always a mistake. It can be used intentionally to group multiple cases that should run the same code.
What this code does: Multiple cases can share the same code by stacking them (intentional fall-through). Saturday and Sunday both print the weekend message; weekdays share the other message.
let day = "Saturday";
switch (day) {
case "Saturday":
case "Sunday":
console.log("It's the weekend!");
break;
case "Monday":
case "Tuesday":
case "Wednesday":
case "Thursday":
case "Friday":
console.log("It's a weekday.");
break;
default:
console.log("Not a valid day.");
}
let day = "Saturday"; stores the string "Saturday".switch (day) { evaluates day once and compares it with the case labels below.case "Saturday": matches the value ("Saturday" === "Saturday"). This case has no code and no break of its own, so execution simply continues into the next line. This is intentional fall-through.case "Sunday": is the second label for the same block of code. Execution falls through this label (without checking it) and reaches the code on the next line. Stacking labels like this means Saturday or Sunday both run the same code."It's the weekend!". This is the output of the program.break; leaves the switch, so the weekday code below is not executed. It is important to put the break after the shared code, not between the stacked labels.case "Monday": is the first of five stacked labels that share one block of code. It is skipped here because the switch has already ended.case "Tuesday": is stacked with the other weekdays and has no code of its own.case "Wednesday": is another stacked label for the same weekday code.case "Thursday": is another stacked label for the same weekday code.case "Friday": is the last of the stacked labels. If the day were any of the five, execution would fall through the labels to the code on the next line."It's a weekday.". Here it is skipped, because the day is Saturday.break; stops the switch after the weekday code, so execution does not fall into default.default: runs when the day matches none of the seven names, for example a misspelled "Saterday"."Not a valid day." for an invalid value. It is skipped because Saturday matched.} ends the switch. The output is It's the weekend!
Here, "Saturday" and "Sunday" share the
same code block by having no statements (and no
break) between their case labels.
The default Case
The default case runs when none of the other cases
match. It is optional, but it’s good practice to include one to
handle unexpected values.
What this code does: switch works with numbers too.
Status code 404 matches its case and prints “Not Found”. The default handles any unmatched value.
let statusCode = 404;
switch (statusCode) {
case 200:
console.log("OK");
break;
case 404:
console.log("Not Found");
break;
case 500:
console.log("Server Error");
break;
default:
console.log("Unknown status code");
}
let statusCode = 404; stores the number 404 (an HTTP status code meaning the page was not found). A switch is not limited to strings: it works with numbers too. Notice that the number has no quotes.switch (statusCode) { evaluates statusCode once and compares it with each case using strict equality.case 200: checks 404 === 200, which is false, so this case is skipped."OK", the message for a successful request. It is skipped.break would end the switch after the 200 code. It is not reached.case 404: checks 404 === 404, which is true. JavaScript starts running the code under this label."Not Found". This is the output of the program.break; leaves the switch, so the cases for 500 and default below are not executed.case 500: would be checked next, but the switch already ended. It handles server errors."Server Error" when the status code is 500.break would end the switch after the 500 code.default: is the fallback for any status code that is not 200, 404 or 500, such as 301 or 403. It is good practice to include it to handle unexpected values."Unknown status code". It is skipped because 404 matched.} ends the switch. The output is Not Found.
The default case does not have to be the last one in
the switch block, but placing it last is the most
common and readable convention.
switch Uses Strict Comparison
A switch statement compares values using strict
equality (===), meaning both the value and the type
must match.
What this code does: switch uses strict equality (===).
The string "5" does not match the number 5, so the string case runs instead.
let value = "5";
switch (value) {
case 5:
console.log("Matched the number 5");
break;
case "5":
console.log("Matched the string \"5\"");
break;
default:
console.log("No match");
}
let value = "5"; stores the string "5" (it has quotes), not the number 5. The two look similar but have different types, and that difference is the point of this example.switch (value) { evaluates value once. Each case is compared using strict equality (===), so both the value and the type must match.case 5: checks "5" === 5. That is false, because a string and a number are different types, even though "5" == 5 would be true with loose equality. So this case does not match."Matched the number 5". It is skipped, because the number case did not match.break belongs to the number case and is not reached.case "5": checks "5" === "5". Both are strings with the same text, so this is true and the case matches.\" sequences are escaped quotes: they place real quotation marks in the output without ending the string. It prints Matched the string "5".break; exits the switch, so default is not executed.default: would run only if neither the number 5 nor the string "5" matched, for example if value were true."No match". It is skipped here.} ends the switch. The output is Matched the string "5". Try changing line 1 to let value = 5; to see the number case match instead.
Even though 5 == "5" is true,
switch only matches the string case here, since it
compares using === rather than ==.
Using Expressions in case Labels
By using switch (true), you can evaluate a
boolean condition in each case, which allows range
checks similar to an if...else if chain.
What this code does: switch (true) can test ranges, similar to else if.
Each case is a condition; the first one that is true wins. Score 82 gives grade B.
let score = 82;
switch (true) {
case (score >= 90):
console.log("Grade: A");
break;
case (score >= 80):
console.log("Grade: B");
break;
case (score >= 70):
console.log("Grade: C");
break;
default:
console.log("Grade: F");
}
let score = 82; stores the number 82. The cases below will test this value against ranges.switch (true) { is a trick for range checks. The value being switched on is the boolean true, so each case below is written as a condition, and the first case whose condition evaluates to true matches (because true === true).case (score >= 90): evaluates 82 >= 90, which is false. JavaScript then compares true === false, which does not match, so this case is skipped."Grade: A" for scores of 90 and above.break would end the switch after the grade A code.case (score >= 80): evaluates 82 >= 80, which is true. Now true === true matches, so this is the first matching case."Grade: B". This is the output of the program.break; leaves the switch, so the remaining cases are not checked. The order of the cases matters here: they are tested from the highest score range to the lowest.case (score >= 70): would also be true for 82, but it is never evaluated, because the earlier match already ended the switch with break."Grade: C" for scores from 70 to 79.break would end the switch after the grade C code.default: runs if no case condition is true, which here means a score below 70."Grade: F". It is skipped because the grade B case matched.} ends the switch. The output is Grade: B.switch vs. if…else
| Aspect | if…else | switch |
|---|---|---|
| Best for | Complex or range-based conditions | Comparing one value against many exact options |
| Comparison type | Any expression | Strict equality (===) by default |
| Readability with many options | Can get long and repetitive | Often clearer and more organized |
| Grouping multiple values | Requires && / || | Fall-through between case labels |
Practical Example
Let’s use a switch statement to handle a simple menu
selection.
What this code does: A function can use switch to return different values.
getMenuPrice("coffee") returns 3.5. Using return exits the function, so break is not required.
function getMenuPrice(item) {
switch (item) {
case "coffee":
return 3.5;
case "tea":
return 2.5;
case "sandwich":
return 6.0;
default:
return 0;
}
}
console.log("Coffee price:", getMenuPrice("coffee"));
console.log("Tea price:", getMenuPrice("tea"));
console.log("Unknown item price:", getMenuPrice("soup"));
function getMenuPrice(item) { defines a reusable function named getMenuPrice. The name in parentheses, item, is a parameter: a placeholder for the menu item that will be passed in when the function is called. Nothing runs yet; this only defines the function.switch (item) { compares the value of the parameter with the cases below, using strict equality. The switch is placed inside the function so that the function can look up a price for any item.case "coffee": matches when item is "coffee".return 3.5; sends the number 3.5 back to whoever called the function and immediately ends the function. Because the function exits, no break is needed here.case "tea": matches when item is "tea".return 2.5; returns the price of tea and exits the function.case "sandwich": matches when item is "sandwich".return 6.0; returns the price of a sandwich. JavaScript stores 6.0 as the number 6. Note that this case is not used by the calls below, but it works the same way.default: handles every item that is not on the menu.return 0; gives back 0 when the item is not recognized, so the function always returns a number.} closes the switch block (the inner brace, indented four spaces).} closes the function body. After this line, getMenuPrice is ready to be called as many times as you like.getMenuPrice("coffee") runs the function with item set to "coffee". The coffee case matches and the function returns 3.5. console.log prints the label and the returned value, separated by a space: Coffee price: 3.5."tea". The tea case matches and returns 2.5, so the output is Tea price: 2.5.getMenuPrice("soup") does not match any case, so the default case returns 0. The output is Unknown item price: 0.
Notice that return inside a case
immediately exits the function, which is why break
is unnecessary after a return statement.
Common Mistakes With switch
- Forgetting
break, causing unintended fall-through into the next case. - Expecting
switchto use loose equality (==) like some other comparisons in JavaScript. - Omitting the
defaultcase, so unexpected values are silently ignored. - Declaring variables with
letorconstdirectly inside acasewithout wrapping it in a block, which can cause scope-related errors. - Using
switchfor complex range checks when a regularif...else ifchain would be clearer.
Declaring Variables Inside a case
Since all case labels share the same block scope,
declaring a variable with the same name in multiple cases can
cause a SyntaxError. Wrapping each case in curly
braces creates its own block scope.
What this code does: When you declare variables inside a case, wrap the body in curly braces
to create a block scope. That avoids conflicts if the same variable name is used in another case.
let action = "add";
let result;
switch (action) {
case "add": {
const message = "Adding items";
result = message;
break;
}
case "remove": {
const message = "Removing items";
result = message;
break;
}
default: {
result = "Unknown action";
}
}
console.log(result);
let action = "add"; stores the string "add". This decides which case will run.let result; declares a variable outside the switch, with no value yet (it is undefined). It is declared here so that it can be used after the switch ends. Variables declared inside the case blocks below would not be visible out here.switch (action) { evaluates action once and compares it with the case labels using strict equality.case "add": { matches because "add" === "add". The opening curly brace after the colon creates a block scope that belongs only to this case.const message = "Adding items"; creates a constant named message. Because it is declared inside the braces of this case, it exists only in this block.result = message; copies the text into the outer result variable, so the value survives after the block ends.break; leaves the switch, so the remove case and default are not executed.} closes the block that began on line 4. The constant message no longer exists after this point.case "remove": { is skipped here, because "add" already matched. It also opens its own block.const message = "Removing items"; uses the same name as in the add case. This is allowed only because each case has its own curly braces. Without the braces, both declarations would share one scope and JavaScript would throw a SyntaxError because message was already declared.result = message; would store the remove text in result. It is skipped here.break; would end the switch after the remove case.} closes the block that began on line 9.default: { handles any action other than "add" and "remove". Using braces here keeps the style consistent, and protects against scope problems if variables are added later.result = "Unknown action"; would run for an unknown action. It is the last case, so no break is needed.} closes the block that began on line 14.} at the left margin ends the switch statement.console.log(result); prints the value stored in result, which was set in the add case. The output is Adding items.Best Practices for switch
- Always include a
breakat the end of each case, unless fall-through is intentional. - Always include a
defaultcase to handle unexpected values. - Wrap each
casebody in curly braces when declaring variables inside it. - Use
switchwhen comparing one value against many specific options; useif...elsefor more complex or range-based logic. - Add a short comment when using intentional fall-through, so future readers know it wasn’t a mistake.
Quick Summary
switchcompares one expression against severalcasevalues using strict equality.breakstops execution from falling into the next case.- Fall-through happens automatically without
break, and can be used intentionally to group cases. defaultruns when no other case matches.switch (true)can be used for range-based conditions similar toif...else if.- Use curly braces around a
casebody when declaring block-scoped variables inside it.
Try It Yourself
Modify the value below. Try changing day to
"Sunday", or to a day not listed, and observe how the
output changes.
What this code does: Practice example: change day to Sunday or another value,
then click Test My Code to see the weekend vs weekday message.
let day = "Wednesday";
switch (day) {
case "Saturday":
case "Sunday":
console.log("It's the weekend!");
break;
default:
console.log("It's a weekday.");
}
let day = "Wednesday"; stores the string "Wednesday". This is the line to edit in the live editor. Try "Sunday", "Saturday", or a value such as "Holiday" and run the code again.switch (day) { evaluates day once and compares it with the case labels using strict equality.case "Saturday": checks "Wednesday" === "Saturday", which is false. Since this label has no code of its own, a match would fall through to the next line.case "Sunday": is stacked with Saturday and shares the same code. It does not match "Wednesday" either."It's the weekend!" for Saturday or Sunday. It is skipped for Wednesday.break; ends the switch after the weekend message, so that default does not also run for weekend days.default: runs when nothing else matches. Because Wednesday is neither Saturday nor Sunday, JavaScript uses this label."It's a weekday.". Note that default also catches any invalid text, so "Holiday" would print the same message.} ends the switch. The output is It's a weekday.Tip: If you find yourself writingif (x === a) ... else if (x === b) ... else if (x === c), that’s usually a strong sign aswitchstatement would express the same logic more clearly.
Understanding switch is useful before moving on to
loops, functions, and more advanced JavaScript concepts.
🧪 Test Your JavaScript Code
Edit the code on the left and click “Run Code” to see the console output on the right.
Click “Run Code” to see the output here.
Code Explanation
The complete example stays visible. Use Previous and Next to move through its logical blocks.
Select Next to begin exploring the code.