How to get return value from switch statement?

Viewed 126185

In chrome's console, when I type:

> switch(3){default:"OK"}
  "OK"

So looks like the switch statement has a return value. But when I do:

> var a = switch(3){default:"OK"}

It throws a syntax error "Unexpected Token switch"

Is it possible to capture the return statement of the switch?

8 Answers

ES6 lets you do this using an immediately-invoked lambda:

const a = (() => {
  switch(3) {
    default: return "OK";
  }
})();

What you are seeing in the chrome dev tools is the completion value of the switch statement. Basically the value of the last evaluated expression (but not quite, e.g. the completion value of var a = 42 is not 42). The completion value is a construct in ECAMScript that is usually hidden from the programmer. Though, it also comes up as the return value of eval().

The grammar for variable assignments expects an expression on its right-hand side so using a switch statement is that place is a syntax error:

"var" <name> "=" <expression> 

Basically the difference between statements and expressions is that expressions compute a value while statements do not. Function calls, arithmetic, and literals are all expressions for example. "If" and "switch" statements are not.

There is no way to capture the completion value of any statement expects perhaps wrapping it in an eval call:

var a = eval('switch (3) { default: "OK" }')
console.log(a) // => "OK"

But using eval for this would not be a good idea.

Unfortunately, there is no great way to archive what you want to do. Like other answers mentioned, you could wrap the switch in a function (or IIFE) and use return statements to get the value out:

const a = (() => {
  switch(3) { default: return "OK"; }
})();

You might find this not to be an ideal solution and you are not the only one having this issue with JavaScript.

It is my understanding that this is one of the motivations of the pattern-matching ECAMScript proposal. But the proposal is in Stage 1 and not yet ready for production use.

Furthermore, you might want to write your code in a way that does not need switch statements at all. A while ago I came across the following pattern that is apparently common in Lua but I never saw it used in JavaScript:

Instead of using a switch statement you could put all your cases as properties in a JavaScript object and use functions as values instead of the logic in the individual case blocks. This might look something like this:

const cases = {
  "FOO": () => 1,
  "BAR": () => 2,
  "BAR": () => 3,
};


const value = "FOO";
const result = cases[value]();
console.log(result); // => 1

Instead of this:

let result;
switch (value) {
    case "FOO":
        result = 1;
        break;
    case "BAR":
        result = 2;
        break;
    case "BAR":
        result = 3;
        break;
}

If you need non-string cases you might want to use a Map.

You can use an object

const a = { [enum.3]: "OK" }[3] ?? "default"
Related