You Probably Don’t Need to Use Switch Statements in JavaScript

You Probably Don’t Need to Use Switch Statements in JavaScript

No switch, no complex code blocks

Switch is convenient: given an expression, we can check whether it matches a bunch of other expressions in a case clause. Consider the following example:

const name = "Juliana";

switch (name) {
  case "Juliana":
    console.log("She's Juliana");
    break;
  case "Tom":
    console.log("She's not Juliana");
    break;
}

When name is "Juliana", we print a message and immediately break out of the block. When inside a switch function, you can omit break by using return directly in the case block.

When there are no matches, the default option can be used:

const name = "Kris";

switch (name) {
  case "Juliana":
    console.log("She's Juliana");
    break;
  case "Tom":
    console.log("She's not Juliana");
    break;
  default:
    console.log("Sorry, no match");
}

Switch is also used heavily in Redux reducers (although Redux Toolkit simplifies the boilerplate a bit) to avoid having lots of if s. Consider the following example:

const LOGIN_SUCCESS = "LOGIN_SUCCESS";
const LOGIN_FAILED = "LOGIN_FAILED";

const authState = {
  token: "",
  error: "",
};

function authReducer(state = authState, action) {
  switch (action.type) {
    case LOGIN_SUCCESS:
      return { ...state, token: action.payload };
    case LOGIN_FAILED:
      return { ...state, error: action.payload };
    default:
      return state;
  }
}

Is there anything wrong with this? Hardly. But is there a better alternative?

Inspiration from Python

This Tweet from Telmo caught my attention. He shows two styles of "switch", one of which is very close to the pattern in Python.

Python doesn't have a switch, which gives us a better alternative. First let's port the code from JavaScript to Python:

LOGIN_SUCCESS = "LOGIN_SUCCESS"
LOGIN_FAILED = "LOGIN_FAILED"

auth_state = {"token": "", "error": ""}


def auth_reducer(state=auth_state, action={}):
    mapping = {
        LOGIN_SUCCESS: {**state, "token": action["payload"]},
        LOGIN_FAILED: {**state, "error": action["payload"]},
    }

    return mapping.get(action["type"], state)

In Python, we can use a dictionary to simulate switch. dict.get() can be used to represent the default statement of a switch.

When accessing a non-existent key, Python will trigger a KeyError error:

>>> my_dict = {

"name": "John",

"city": "Rome",

"age": 44

}

>>> my_dict["not_here"]

# Output: KeyError: 'not_here'

The .get() method is a safer approach because it will not raise an error and you can specify a default value for a non-existent key:

>>> my_dict = {

"name": "John",

"city": "Rome",

"age": 44

}

>>> my_dict.get("not_here", "not found")

# Output: 'not found'

Therefore, this line in Python:

return mapping.get(action["type"], state)

The equivalent in JavaScript is:

function authReducer(state = authState, action) {
  ...
    default:
      return state;
  ...
}

Use dictionary to replace switch

Consider the previous example again:

const LOGIN_SUCCESS = "LOGIN_SUCCESS";
const LOGIN_FAILED = "LOGIN_FAILED";

const authState = {
  token: "",
  error: "",
};

function authReducer(state = authState, action) {
  switch (action.type) {
    case LOGIN_SUCCESS:
      return { ...state, token: action.payload };
    case LOGIN_FAILED:
      return { ...state, error: action.payload };
    default:
      return state;
  }
}

Without using switch we can do this:

function authReducer(state = authState, action) {
  const mapping = {
    [LOGIN_SUCCESS]: { ...state, token: action.payload },
    [LOGIN_FAILED]: { ...state, error: action.payload }
  };

  return mapping[action.type] || state;
}

Here we use computed properties in ES6. Here, the properties of mapping are calculated on the fly based on two constants: LOGIN_SUCCESS and LOGIN_FAILED.
The value corresponding to the attribute is object destructuring, which comes from ES9 (ECMAScript 2018).

const mapping = {
  [LOGIN_SUCCESS]: { ...state, token: action.payload },
  [LOGIN_FAILED]: { ...state, error: action.payload }
}

What do you think of this approach? It may have some limitations for switches, but it may be a better solution for reducers.

But how does this code perform?

How is the performance?

The performance of switch is better than that of dictionary. We can test this using the following example:

console.time("sample");
for (let i = 0; i < 2000000; i++) {
  const nextState = authReducer(authState, {
    type: LOGIN_SUCCESS,
    payload: "some_token"
  });
}
console.timeEnd("sample");

Measure them about ten times,

for t in {1..10}; do node switch.js >> switch.txt; done

for t in {1..10}; do node map.js >> map.txt; done

The above is the details of why you may not need to use the switch statement in JavaScript. For more information about JavaScript switch statements, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Summary of the use of three for loop statements in JavaScript (for, for...in, for...of)
  • Detailed explanation of common for loop in JavaScript statements
  • Summary of optimization techniques for conditional statements in JavaScript
  • How to run js statements in python
  • An article to help you understand JavaScript-statements

<<:  A brief discussion on Mysql specified order sorting query

>>:  Mysql5.6.36 script compilation, installation and initialization tutorial

Recommend

Detailed explanation of Tomcat's commonly used filters

Table of contents 1. Cross-domain filter CorsFilt...

React hooks introductory tutorial

State Hooks Examples: import { useState } from &#...

HTML table tag tutorial (33): cell vertical alignment attribute VALIGN

In the vertical direction, you can set the cell a...

The neglected special effects of META tags (page transition effects)

Using js in web design can achieve many page effec...

Solution to css3 transform transition jitter problem

transform: scale(); Scaling will cause jitter in ...

Apache Spark 2.0 jobs take a long time to finish when they are finished

Phenomenon When using Apache Spark 2.x, you may e...

How to configure Bash environment variables in Linux

Shell is a program written in C language, which i...

Detailed explanation of how to find the location of the nginx configuration file

How can you find the location of the configuratio...

Summary of 50+ Utility Functions in JavaScript

JavaScript can do a lot of great things. This art...

How to compile and install opencv under ubuntu

Easy installation of opencv2: conda install --cha...

JS canvas realizes the functions of drawing board and signature board

This article shares the specific code of JS canva...

uniapp Sample code for implementing global sharing of WeChat mini-programs

Table of contents Create a global shared content ...

Practical MySQL + PostgreSQL batch insert update insertOrUpdate

Table of contents 1. Baidu Encyclopedia 1. MySQL ...

Detailed explanation of single-row function code of date type in MySQL

Date-type single-row functions in MySQL: CURDATE(...