JavaScriptEasy

How does the switch statement work?

01

The Short Answer

The switch statement evaluates an expression and matches its value against multiple case clauses using strict equality (===). When a match is found, it executes the code in that case block and all subsequent cases unless a break statement stops it (this is called "fall-through"). It's an alternative to long if...else if chains when you're comparing a single value against multiple known options. Switch is most useful when you have 3+ discrete values to check against.

02

Basic Syntax and Behavior

A switch statement has three key parts: the expression being evaluated, case labels to match against, and an optional default clause that runs when no case matches. Each case needs a break to prevent fall-through to the next case. The default clause is like the else in an if/else chain — it catches everything that didn't match.

switch-basics.tstypescript
function getStatusMessage(status: number): string {
  switch (status) {
    case 200:
      return 'OK';
    case 301:
      return 'Moved Permanently';
    case 404:
      return 'Not Found';
    case 500:
      return 'Internal Server Error';
    default:
      return `Unknown status: ${status}`;
  }
}

getStatusMessage(200)  // 'OK'
getStatusMessage(404)  // 'Not Found'
getStatusMessage(418)  // 'Unknown status: 418'

// Equivalent if/else chain — more verbose with many cases:
function getStatusMessageIfElse(status: number): string {
  if (status === 200) return 'OK';
  else if (status === 301) return 'Moved Permanently';
  else if (status === 404) return 'Not Found';
  else if (status === 500) return 'Internal Server Error';
  else return `Unknown status: ${status}`;
}
03

Fall-Through Behavior

Without a break (or return), execution "falls through" to the next case — it keeps running code until it hits a break or the end of the switch block. This is sometimes intentional (grouping multiple cases that share the same logic) but is often an accidental bug. Most linters flag fall-through without an explicit comment.

fall-through.tstypescript
// ⚠️ Accidental fall-through — common bug
function getDayType(day: string): string {
  let type = '';
  switch (day) {
    case 'Monday':
      type = 'Start of work week';
      // Missing break! Falls through to Tuesday's case
    case 'Tuesday':
      type = 'Regular work day';
      break;
    default:
      type = 'Unknown';
  }
  return type;
}
getDayType('Monday')  // 'Regular work day' — NOT what we wanted!

// ✅ Intentional fall-through — grouping cases
function isWeekend(day: string): boolean {
  switch (day) {
    case 'Saturday':
    case 'Sunday':
      return true;  // Both cases share this return
    default:
      return false;
  }
}

// ✅ Grouping with shared logic
function getQuarter(month: number): number {
  switch (month) {
    case 1: case 2: case 3:
      return 1;
    case 4: case 5: case 6:
      return 2;
    case 7: case 8: case 9:
      return 3;
    case 10: case 11: case 12:
      return 4;
    default:
      throw new Error(`Invalid month: ${month}`);
  }
}
04

Strict Equality Comparison

Switch uses strict equality (===) for comparisons — no type coercion happens. This means case '1' won't match the number 1, and case 0 won't match the string '0'. This is actually a benefit over loose comparisons, but it can surprise developers who expect type coercion.

strict-equality.tstypescript
const value = '1';  // string

switch (value) {
  case 1:           // number — won't match!
    console.log('number 1');
    break;
  case '1':         // string — matches
    console.log('string 1');
    break;
}
// Output: 'string 1'

// This also means null and undefined are distinct:
switch (null) {
  case undefined:   // won't match — null !== undefined
    console.log('undefined');
    break;
  case null:        // matches
    console.log('null');
    break;
}
05

Switch vs Object Lookup

For simple value-to-value mappings, an object (or Map) lookup is often cleaner than a switch statement. It's more concise, easier to extend, and avoids the fall-through footgun entirely. Use switch when you need complex logic per case (multiple statements, side effects). Use object lookups when each case just maps to a single value.

switch-vs-object.tstypescript
// Switch — verbose for simple mappings
function getColorName(code: string): string {
  switch (code) {
    case 'r': return 'Red';
    case 'g': return 'Green';
    case 'b': return 'Blue';
    default: return 'Unknown';
  }
}

// Object lookup — cleaner for value mappings
const COLOR_NAMES: Record<string, string> = {
  r: 'Red',
  g: 'Green',
  b: 'Blue',
};

function getColorName(code: string): string {
  return COLOR_NAMES[code] ?? 'Unknown';
}

// Use switch when cases have complex logic:
function handleAction(action: { type: string; payload?: unknown }) {
  switch (action.type) {
    case 'INCREMENT':
      counter++;
      logAnalytics('increment');
      updateUI();
      break;
    case 'RESET':
      counter = 0;
      clearHistory();
      break;
  }
}
06

Why Interviewers Ask This

This is a fundamentals question that tests whether you understand fall-through behavior (and its risks), know that switch uses strict equality, can identify when switch is better than if/else or object lookups, and understand scoping within case blocks (variables declared in one case are visible in others unless you use braces).

Quick Revision Cheat Sheet

Comparison: Uses === (strict equality) — no type coercion

Fall-through: Without break, execution continues into the next case

Grouping cases: Intentional fall-through: case 'a': case 'b': return result

default clause: Catches unmatched values — like else in if/else

vs object lookup: Use objects for simple mappings, switch for complex per-case logic

Scoping tip: Wrap case bodies in {} if you declare variables to avoid scope leaks