DEV Community

Cover image for Switch is ok

Switch is ok

Pragmatic Maciej on May 08, 2020

Switch statement had lately some bad fame, some developers avoid it as possible, and others advocate to deprecate it. Almost as if it would be some...
Collapse
 
josemunoz profile image
José Muñoz

I am in the bandwagon of object literals over switches, I know it doesn't have a tremendous impact but combining it with some ES8 features like optional chaining and nil colascing makes it even better IMO:

const counter = (initialState = 0) => (action) => {
  const nextState = {
    'INCREMENT': () => initialState + 1,
    'DECREMENT': () => initialState -1
  }[action.type]?.() ?? initialState

return nextState
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
macsikora profile image
Pragmatic Maciej

It goes to the point that switch is not expression. Don't get we wrong optional chaining and nulish colascing are great feature, but I don't believe using them as you have shown is a good example. It's just not needed here.

Collapse
 
josemunoz profile image
José Muñoz

Hahaha I agree completely, specially nil colascing which would easily be replaced with a logical or instead, it’s just a personal preference

Collapse
 
vonheikemen profile image
Heiker

The best thing about switch statements is that you're not limited to strings.

function fun(data) {
  switch(data.constructor) {
    case Symbol:
      return 'You gave me a symbol';
    case String:
      return 'No strings attached';
    case Array:
      return 'To map or not to map';
    case Number:
      return 'something something 42';
    case Boolean:
      return 'is it true?';
    case Promise:
      return 'maybe, maybe not';
    case Function:
      return "Don't call us, we'll call you";
    case (async () => {}).constructor:
      return 'Ooh, fancy stuff';
    default:
      return 'what?'
  }
}

const some_fun = function() {};
const async_fun = async function() {};

fun(['hello']);
fun(74);
fun('this');
fun(Symbol('What?'));
fun(true);
fun(some_fun);
fun(async_fun);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
macsikora profile image
Pragmatic Maciej

Nice. Thanks for sharing

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Your example with the object literal is overly long:

const hero = (x = "default") => ({
    "DC": "Batman",
    "Marvel" : "Wolverine",
    "default": "Spiderman"
}[x])
Enter fullscreen mode Exit fullscreen mode
Collapse
 
macsikora profile image
Pragmatic Maciej

I have waited for that 😉

Collapse
 
bytebodger profile image
Adam Nathaniel Davis

I've been in both camps before. I think I went at least 10 years without writing a switch/case anywhere. But in the last several years, I've actually come back to switch statements. It's not like I use them everywhere - or even, often. But I do use them. IMHO, the "proper" use-case for switches is whenever you are checking one variable against a set of known values. I do not like any use of a switch where people are trying to embed logic that goes beyond the basic idea of a switch.

Also, although I'm, admittedly, a Certified Redux Hater, it's hard for anyone to love Redux and hate switches. I've even seen Redux fanboys grumble about switches that are written outside of their reducers - but they're perfectly fine using a ton of switches inside their reducers. Such pedantic distinctions make little sense.

Railing against the use of switch makes no more sense than railing against a while loop. Are while loops usually the "right" choice?? No. But there are absolutely times when a while loop is the right choice.

Collapse
 
nosknut profile image
nosknut

Can we all just gather around the campfire and agree that redux is an unmatched headache? 😂 People dump implementation logic of 50 lines in their reducers and the code becomes impossible to follow in large projects.

Collapse
 
torstendittmann profile image
Torsten Dittmann

My favourite Javascript switch feature is the ability to use switch(true) followed by cases with with comparison operations.

Looks much cleaner compared to a lot of if/else.

Collapse
 
siy profile image
Sergiy Yevtushenko • Edited

New and shiny doesn't mean better.

Smaller doesn't mean better 😂, when you look at both for sure you need a little more time for the second.

I'm constantly telling those phrases to Kotlin fans :)

Collapse
 
danomatic profile image
Dan Blaisdell • Edited
const counter = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}
Enter fullscreen mode Exit fullscreen mode

can just be

const increment = (number = 0) => {
  return number + 1
}
const decrement = (number = 0) => {
  return number - 1
}
Enter fullscreen mode Exit fullscreen mode

unless you need it to be so dynamic (uses user input or is an event handler that lacks types) that your code doesn't know which action to take without user input. if you end up writing:

counter(5, 'increment')
Enter fullscreen mode Exit fullscreen mode

...you are just converting function names into string names and making your code breaky and complicated and too clever for its own good

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
nosknut profile image
nosknut

Depends on how extreme it is. If i have to spend an extra 10 seconds reading your code to understand something that a switch could tell me in 2 lines, and i have to do that every time i read your code 20 times a day for a year, we are having a meeting 😂 Otherwise, people can do whatever they want for all i care.

Collapse
 
ryands17 profile image
Ryan Dsouza

+1, although I would love for pattern matching to land in JavaScript as it's the best of both worlds :)

Collapse
 
macsikora profile image
Pragmatic Maciej

Yes you are right, I have wrongly made a title of this paragraph. Changed already

Collapse
 
ifarmgolems profile image
Patrik Jajcay

Lodash _.cond with lodash/fp version for the win!