loading...

Replace your switch statement and multiple "if and else", using Object Literals - [en-US].

lukyhenson profile image Tauan Tathiell ・3 min read

Alt Text

So First, What is Switch Statement?

A switch is a function that receives data, and that data will be analyzed, if this data is equal to one of our cases, it makes the instructions in that case and returns a value.

function UserPolicy(type) {
  switch(type) {
    case 'admin':
      return 'This User is Admin!'
      break
    case 'client':
      return 'This User is Client!'
      break
    case 'salesman':
      return 'This User is Salesman!'
      break
    default:
      return 'Ops, this guy doesn\'t have user profile'
  }
}

UserPolicy() // 'Ops, this guy doesn't have user profile'
UserPolicy('admin') // "This User is Admin!"

It’s similar to if and else statements, but it should evaluate a single value – inside the switch we use a case to evaluate against each value.

When you are using lots of else if statements, something very wrong and generally you should use something like a switch as it’s more suited for the purpose and intention. Here’s some else if abuse:

function UserPolicy(type) {
  let userType
  if (type === 'admin') {
    userType = 'This User is Admin!'
  } else if (type === 'client') {
    userType = 'This User is Client!'
  } else if (type === 'salesman') {
    userType = 'This User is Salesman!'
  } else {
    userType = 'Ops, this guy doesn\'t have user profile'
  }

  return `User is type: ${userType}`
}

Problems with switch

There are multiple issues with switch, from its procedural control flow to the non-standard-looking way it handles code blocks, the rest of JavaScript uses curly braces yet switch does not. Syntactically, it's not one of JavaScript's best, nor is its design. We're forced to manually add break; statements within each case, which can lead to difficult debugging and nested errors further down the case should we forget! We have to treat this with caution.

We often use Object lookups for things in JavaScript, often for things, we would never contemplate using switch for - so why not use an Object literal to replace the switch? Objects are much more flexible, have better readability and maintainability and we don't need to manually break; each case. They´re a lot friendlier on new JavaScript developers as well, as they´re standard Objects.

Reasons not to use switch

  • As the number of “cases” increases, the performance of the object (hash table) gets better than the average cost of the switch (the order of the matter of the case). The object approach is a hash table lookup, and the switch has to evaluate each case until it hits a match and a break.

  • More maintainable and readable. We also don’t have to worry about break; statements and cases falling through – it’s just a plain Object.

Normally, we would put a switch inside a function and get a return value. Let's do the same here and make the switch case a usable function with a return of an Object Literal:

function UserPolicy(type) {
  // We create a const that receives an object and each of its properties.
  // will be the values corresponding to our types
  const Users = {
    admin: 'This User is Admin!',
    client: 'This User is Client!',
    salesman: 'This User is Salesman!',
    default: 'Ops, this guy doesn\'t have user profile'
  }

  return Users[type] || Users.default
}

UserPolicy() // 'Ops, this guy doesn't have user profile'
UserPolicy('admin') // "This User is Admin!"

Overview

Object literals are a more natural control of flow in JavaScript, the switch is a bit old and clunky and prone to difficult debugging errors. Objects are more extensible, maintainable, and we can test them a lot better. They’re also part of a design pattern and very commonly used day to day in other programming tasks. Object literals can contain functions as well as any other Object type, which makes them really flexible! Each function in the literal has function scope too, so we can return the closure from the parent function.

//I'm not dictating the rule - it's just another way of solving our everyday problems

Posted on by:

lukyhenson profile

Tauan Tathiell

@lukyhenson

I'm passionate for javascript

Discussion

markdown guide
 

Nice, except for your default user. Your code cannot distinguish between "default" type and some random string.

But I like your approach.

I would use chaining of ternary operators instead


const distinguish = type =>
  type === 'admin'
    ? 'This is admin'
    : type === 'user'
    ? 'This is user'
    : type === 'manager'
    ? 'This is manager'
    : 'Uknown guy, denied';

['admin', 'manager', 'nonsense'].map(value => console.log(distinguish(value)));

 

From syntactic point of view ternary is way more terrible to read instead of switch :d

 

Do you think so?

Still, switch is error-prone construction while chaining ternany is one expression.

Yes, I do because in my work’s project we have many ternary operators used and when they are long it’s brain damaging while reading them. Again - just from synthetic point of view :)

Well, I guess it depends. The simplicity of conditions is basic requirement

 

thanks for ur review, i put this default user just to show a sample how to use. but i understand ur point .. i'll change some code's soon... one more time Thanks xD

 

I was just nitpicking I guess. :)

I added a sample code to my previous comment. You may want to check it.

Thanks man .. i liked a lot your approach...
// I'm not dictating the rule - it's just another way of solving our everyday problems. hehehehe

 

Most of your arguments against SWITCH are in fact it's features. It's like the derpy linters that throw a hissy-fit if you drop-through, one of the entire reasons to use switch in the first place. Oh noes, you have to say break, return, or continue, notz thatz. :/

Though I'm often dismayed how often I see break; after a return; (hurr-durrz) or how many people don't realize continue can also be used there.

From an efficiency standpoint, your claims of disadvantages of switch are more myth than fact. JavaScript table lookups are still going to do comparisons, you are manually coding such a comparison so if anything is going to be slower in execution, it's probably your (Users[type] || Users.default) given how piss poor the performance of JS object indexes are. JUST like the painfully bad performance of JS' ALLEGED arrays. (that are in fact pointered lists).

That said, it's often better to use the object approach you mention for code clarity or organization sake, it's an obvious answer in a lot of situations, but comparing it to IF or SWITCH? Yeah, no.

 

Thanks for ur review.. i wrote this article to pass, what i'm leraning .. how i said "//I'm not dictating the rule - it's just another way of solving our everyday problems" ... i don't have 40 years in programming .. u have more arguments then me , i know it .. i was trying to share something cool .. that i learned .. i'm sorry about that :D

 

I like your approach better, and agree with your logic for using it. keep it up

Thanks man ... let's keep sharing knowledge...

 

Nice article and interesting approach. Thanks!
I have a question however. Why would you use methods to return the string instead of assigning this string to a property like so:

const Users = {
  admin: 'This User is Admin!',
  client: 'This User is Client!',
  salesman: 'This User is Salesman!',
  default: 'This User is MasterUser'
}

I mean wouldn't it be more clean and straightforward way?

 

Hey man ... thanks .. so in the project that i'm current working i used methods to change the data and other things ... it was just a mistake hehehe i'm sorry .. your approach is absolutelly correct... thanks for your review i'm going to edit it ..

 

I was about to comment with the same when I saw this has already been suggested :)
One more cool little enhancement will allow you to adhere to immutability principle (that is if you'd like to prevent anyone from changing your object properties somewhere in the code later):

Object.freeze(Users)

From now on your object literal is readonly.

 

hey man thanks for the comment :D

 
 

Thanks man... I'm going to do that for all my articles .. i'm trying to share to our community, everything i'm learning :D

 

You're welcome and I appreciate sharing your knowledge/experience :)

 

I think this should be benchmarked to prove that this construct is better than the switch,
my guess is it is not.

 

I take this printscreen by benchmark test ...

altimage

 

This will be pretty neat if you have super long switch in React reducer for instance =] Thanks for the article! It’s nice to know another way of doing things!

 

Yes man .. i like this approach .. i dont guess this will solve all my problems but is a cool approach... thanks for your review

 

Very cool. Thanks for sharing. One issue I can see that you should be aware of is that you won't get an accurate code coverage result for testing, as it will not be seen as branches.

 

Thanks for your review man .. i'll update this article or create another to update with new things

 

I liked the way you explained. Will use object literals in my future projects.

 

Hey man appreciate that.. thanks a lot