Constants In JavaScript Switch
Tags: webdev, javascript
Published: 2020-10-12 13:46:45

---
title: Constants In JavaScript Switch
published: true
description: I recently added a feature to some client code. I won't show the code here, but it was a simple copy-paste with a minor set of changes to ensure the new code executed. The code failed miserably and ran me down an interesting rabbit hole.
series: JavaScript Tips
tags: WebDev, JavaScript 
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/yj4efe4p2johylppnsx9.png
---

I recently added a feature to some client code. I won't show the code here, but it was a simple copy-paste with a minor set of changes to ensure the new code executed. The code failed miserably and ran me down an interesting rabbit hole.

The original version of the code when I began working on this project was a long IF-THEN, ELSE-IF block. It made sense to shift to a SWITCH statement ... making the code easier to read and understand.

I ran into an issue that is one of those, "I knew that" moments where my understanding of JavaScript's internal workings went up another notch.

## Original Code

The original IF-ELSE, ELSE-IF block went something like this ...

``` javascript
const demoSwitch = () => {
  const demo = {
    first: 1
  };

  if (demo.first === 1) {
    const result = 1;
    return result;
  } else if (demo.second === 2) {
    const item = 2;
    return item;
  } else {
    return -1;
  }
};
```

Now, this example is super-simplified, to allow this article to focus on the true issue. There were specific reasons in the original code why `result` and `item` were used. This allowed the first round of refactoring to work correctly, as we'll see later.

### Conversion to Switch

With a basic understanding of the code above, it got converted to something like this ...

```javascript
const demoSwitch = () => {
  const demo = {
    first: 1
  };

  switch (demo.first) {
    case 1:
      const result = 1;
      return result;
    case 2:
      const item = 2;
      return item;
    default:
      return -1;
  }
};
```

Looking at this code, an experienced developer would begin to question some of the decisions that lead to the return lines within the CASES. However, this is simplified code and in its original form, the code has good reason the maintain this form.

## Breaking the Switch

Now, as was said earlier, a new feature was added that paralleled another existing feature. The switch above needed an additional case.

This is where the problem started (and ended).

```javascript
const demoSwitch = () => {
  const demo = {
    first: 1
  };

  switch (demo.first) {
    case 1:
      const result = 1;
      return result;
    case 2:
      const item = 2;
      return item;
    case 3:
      const result = 3;
      return result;
    default:
      return -1;
  }
};
```

This code (before it is even executed) returns the following error: `Uncaught SyntaxError: Identifier 'result' has already been declared`.

I was stumped for a minute, tried a minor adjustment to the code.

```javascript
const demoSwitch = () => {
  const demo = {
    first: 1
  };

  let result = -1;
  switch (demo.first) {
    case 1:
      result = 1;
      return result;
    case 2:
      const item = 2;
      return item;
    case 3:
      result = 3;
      return result;
    default:
      return result;
  }
};
```

This worked.

Here's another pattern suggested in the comments ...

```javascript
const demoSwitch = () => {
  const demo = {
    first: 1
  };

  switch (demo.first) {
    case 1: {
      const result = 1;
      return result;
      }
    case 2: {
      const item = 2;
      return item;
      }
    case 3: {
      const result = 3;
      return result;
      }
    default:
      return -1;
  }
};
```

This pattern works, as well!

Thanks to **[Kostia Palchyk](https://dev.to/kosich)**.

## Conclusion

Basically, this issue was about scope.

As a reminder:

* Declaring a variable using `var` uses the function-level scope.
* Declarations using `let` and `const` are block-level scoped (think, wrapped in parentheses `{}`).

If the variable `result` had been declared using:

* `var`, it would have been hoisted and redeclaration would have occurred later in the code.
* `let`, declaration and redeclaration at the block-level would have occurred.

The variable(s) were declared using `const`, and therefore could not be redeclared at the same block-level.

While this seems like a simple thing, it is one of those little issues that can cause some consternation when a developer comes across it.