DEV Community

Discussion on: 5 ways to refactor if/else statements in JS functions

Collapse
 
bugb profile image
bugb

Suppose you have a code like this:

function foo(arg) {
  if (arg === "a") return 1
  if (arg === "b") return 2
  return 3 //default value
}
Enter fullscreen mode Exit fullscreen mode

You can use something likes this instead of the example above or switch case:

const mapping = {
  a:  1.
  b:  2,
}
function foo(arg) {
  return mapping[arg] || 3;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
sylwiavargas profile image
Sylwia Vargas

Oh, yes! Totally — and thank you! I actually wanted to include this as well but had to run for a lecture. I'll include this wonderful example (I may just change the names so it's easier for tired folks to follow) in the blog tomorrow — look for the shoutout!

Collapse
 
yerlanyr profile image
yerlanyr

This thing I use a lot!

function foo(arg) {
  if (arg === "a") return 1
  if (arg === "b") return 2
  return 3 //default value
}
Enter fullscreen mode Exit fullscreen mode

At this point I always format if statements as if code block, because condition in if statement could be very long so that return would be lost dangling somewhere outside of field of view which could lead to bad mistakes.

function foo(arg) {
  if (arg % 3 === 0 && arg % 5 == 0 /* let's pretend there is very long condition*/) return 'foobar'
  if (arg % 3 === 0) return 'foo'
  if (arg % 5 === 0) return 'foo'
}
Enter fullscreen mode Exit fullscreen mode

Data structures are good for reducing code's complexity. Sometimes it is clearer to use switch case or if's.

Collapse
 
sylwiavargas profile image
Sylwia Vargas

I love these examples — thank you!

condition in if statement could be very long so that return would be lost dangling somewhere outside of field of view
I really couldn't agree more. This is definitely one of the main things that bother me about JS specifically — that there's no strict standard/expectation of writing really short code.

Collapse
 
sqlrob profile image
Robert Myers

Personally, I'm a little torn on this pattern. It's compact, and I've definitely used it.

But, IMHO, it increases the cognitive load of the code, you now have two places to look for what it's doing.

Collapse
 
eecolor profile image
EECOLOR

it increases the cognitive load of the code, you now have two places to look for what it's doing

For that reason in some instances I use this:

function foo(arg) {
  return (
    arg === 'a' ? 1 :
    arg === 'b' ? 2 :
    3
  )
}
Enter fullscreen mode Exit fullscreen mode

or this:

function foo(arg) {
  return {
    a:  1,
    b:  2,
  }[arg] || 3
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
sylwiavargas profile image
Sylwia Vargas

Yeah, it's definitely less "user-friendly" or "beginner-friendly". Coming from Ruby, it gave me chills but also I was really excited for the shorthand properties so — I'm as torn as you are there!

Collapse
 
johnylab profile image
João Ferreira • Edited

I like too use mapping objects for everything, but never put a default inside the function. So all my attention is driven to the object. If the function doesn't find a value in the object, it does nothing and returns null, if needed a value.

Thread Thread
 
johnylab profile image
João Ferreira

"too" was mistype, but let it be

Collapse
 
_hs_ profile image
HS • Edited

And performance impact. Using a map (object whatever the name) should introduce indexing operation in the background. On the other hand what if arg = null or arg = 123 or so? You need to handle all the cases instead of having simple switch with the default. Or even just using if's until you actually need more than 3 cases.

Thread Thread
 
rasmusvhansen profile image
rasmusvhansen • Edited

I doubt there is any real world performance issue here. And as soon as you have more than 2 cases, this is much more readable than a bunch of if statements.

Regarding handling arg=null or arg=123, I don't think I see the issue.
That is handled by the

 return mapping[arg] || 3;
Enter fullscreen mode Exit fullscreen mode

part.

Thread Thread
 
_hs_ profile image
HS • Edited

I highly doubt that using objects instead of switches and ifs has same performance. I'm not limiting it to this scenario but talking about generic overview why should one avoid switches and ifs in favour of objects or hash maps. Reason I'm asking is because I know for a fact that compilers (including JIT ones) and maybe some interpreters have really good optimizations which can even remove branching in some cases but I have no idea would such thing kick in for objects in JS. I know that c++ compiler since 2017 or so has really good optimizations that can turn generics, branching, hahsmaps into few instructions all together. There was a nice conf were, I forgot his name, wrote code on left side and on the right there was assembly outout. I also know JIT in Java will sometimes kick in an replace some of your code with shorter instructions than on first complie. Question is will such things be done by WebKit or others for JS.
Reagarding the safety again it's about generic thing not thi particular piece. It's much easier to have switch with default case and even shorter than objects and relying that || will not be forgotten

Thread Thread
 
rasmusvhansen profile image
rasmusvhansen

I think we are both right here.
You are right that there probably is a difference in performance.
And I am right that in the real world it will make no difference*.
I learned to always prefer readability and then profile if something is slow. It is usually not what you think that is slowing you down.

*Except in that 0.001% weird edge case

Thread Thread
 
xtofl profile image
xtofl

Fyi . The c++ tool mentioned would be godboldt.org.