Switch Scoping

Stefan Janssen
17-12-2018

Variable scoping is one of the first things a developer should learn about. I thought I fully understood scoping, until I recently discovered that I missed something which stops the code from compiling or running. I’ve been programming for about ten years now and it kind of amazed me I missed something this vital.

As the title suggests this post is all about scoping with switch statements. If you don’t know scoping yet I suggest getting to know about scopes first. I’ve always learned to declare variables in the most specific scope possible since we don’t want to pollute the outer scopes.

Now let’s get to those switch statements this post is all about. In most languages a scope is created for the switch statement itself, but not for each individual case. This can cause some issues as shown in the following example:

let value = 1;

switch (value) {
    case 0:
        let messageValue = 5;
        console.log("message: " + messageValue);
        break;
    case 1:
        let messageValue = "A string";
        console.log("message: " + messageValue);
        break;
    case 2:
        let messageValue = true;
        console.log("message: " + messageValue);
        break;
}

This small piece of code might seem fine on first glance, but once we apply hoisting things suddenly become a lot clearer. The following code is not valid, but is just a visualisation of hoisting applied to variables inside a switch statement.

let value = 1;

switch (value) {
    let messageValue;
    let messageValue;
    let messageValue;
    case 0:
        messageValue = 5;
        console.log("message: " + messageValue);
        break;
    case 1:
        messageValue = "A string";
        console.log("message: " + messageValue);
        break;
    case 2:
        messageValue = true;
        console.log("message: " + messageValue);
        break;
}

As you can see, a variable with the name messageValue has been declared three times. This results in the following error: Uncaught SyntaxError: Identifier ‘messageValue’ has already been declared.

There are two ways solve this issue. The first way is declaring the variable outside of the switch This is not a favored solution since the value of messageValue is not used outside of the scope of the switch this means we are polluting the outer scope. An, in my opinion, better way to solve this is by creating an extra scope for each of the cases like in following example:

let value = 1;

switch (value) {
    case 0: {
        let messageValue = 5;
        console.log("message: " + messageValue);
        break;
    }
    case 1: {
        let messageValue = "A string";
        console.log("message: " + messageValue);
        break;
    }
    case 2: {
        let messageValue = true;
        console.log("message: " + messageValue);
        break;
    }
}

The braces added here create a new scope for each case and keeps conflicts between cases out of the way. An added bonus is that they also provide an option for collapsing since not all editors will collapse a single case case statement, but they will collapse on a new scope.

As I’ve said before I’ve been programming for about ten years and have only seen this usage once or twice and it seemed really weird to me. Now I’ve found out why it is used I am tempted to apply this for most, if not all, switch statements I will make going forward.

LEAVE A REPLY

you might also like