76

What's the difference between:

switch (expression) {
    case:
      somethings;
      break;
}

and

switch (expression) {
    case: {
      somethings;
      break;
    }
}

At first I thought that I could return an object literal like so, but it turns out it's a syntax error. What's the difference actually?

Example from another question: How to pass switch statement as function argument in Javascript ES6?

Community
  • 1
  • 1
Aurimas
  • 2,577
  • 5
  • 26
  • 37

2 Answers2

129

Curly braces used in this way establish their own block scope, in which you can define local let variables or const constants:

switch (false) {
    case true: {
      let x = "bar";
      console.log(x);
      break;
    }

    case false: {
      let x = "baz";
      console.log(x);
      break;
    }
}

The example would throw without nested block scopes, since multiple let/const declarations with the same identifier are not allowed within the same scope in Ecmascript 2015.

Please note that the switch statement creates a block scope itself, i.e. whether you use nested block scopes or not, let/const declarations inside switch don't leak into the parent scope.

However, in the context of switch, curly brackets are also used purely decorative, to visually highlight the blocks of the individual case branches.

  • 3
    _"They highlight the block of each case visually"_ That would be decoration, not syntactic sugar. _"this isn't really necessary in most cases"_ It would be more useful to describe when it **is** necessary. – a better oliver Feb 27 '17 at 10:31
  • Hm, is there a strict definition of syntactic sugar? –  Feb 27 '17 at 10:35
  • 1
    syntactic sugar = simpler syntax. Adding braces is not exactly simpler ;) _"If you don't terminate cases with break, different let/const variables within cases might interfere with each other"_ It's one scope, so two declarations with the same identifier will throw an error, `break` or not. – a better oliver Feb 27 '17 at 11:36
  • @zeroflagL Your second statement is definitely right. You caught me! Anyway, which syntax is simpler is highly opinion based, so I leave it at syntactic sugar. You offer an alternative term in your comment, so people can choose their favorite one. –  Feb 27 '17 at 12:28
  • That's a good point. I would say that optional braces here fall into the same category as in if/else if/else. – Estus Flask Feb 27 '17 at 12:32
  • 14
    _"which syntax is simpler is highly opinion based"_ That's not the point. Take `a ** b` instead of `Math.pow(a,b)`. Both mean the same, but one is shorter / more concise. That's syntactic sugar. But `case 1: let x = 2` and `case 1: { let x = 2 } are completely different in their outcome. It's not just different syntax, it **is** different. An apple is not syntactic sugar for an orange. – a better oliver Feb 27 '17 at 13:08
  • @zeroflagL I updated my answer according to your comments, so your effort was hopefully not in vain. –  Feb 27 '17 at 14:05
  • @zeroflagL if there are different runtimes associated with the two calls, I'm not sure I would label it as syntactic sugar - http://stackoverflow.com/questions/41679191/why-is-math-pow-sometimes-not-equal-to-in-javascript – cchamberlain Feb 27 '17 at 18:52
  • @cchamberlain An spec-compliant engine runs the same operation. – a better oliver Feb 28 '17 at 08:36
7

you have to use curly brackets:

  1. when creating more block scoped variables (const / let) with the same name
    • according to spec MDN web docs
    • ERROR: Uncaught SyntaxError: Identifier 'variablename' has already been declared
  2. when using eslint in default settings and using even single one (const / let)
    • according to rule no-case-declarations
    • ERROR: Unexpected lexical declaration in case block no-case-declarations
Michal Miky Jankovský
  • 3,089
  • 1
  • 35
  • 36