Honestly a lot of the time people say "code smell" I get the nasty feeling what they're really…
By: Jason Knight
Tags: JavaScript, Code Smell, Clean Code, Software Development, Programming

Honestly a lot of the time people say "code smell" I get the nasty feeling what they're really saying is "I'm too stupid to use this, so nobody else should be allowed to."

They get upset at their having made one mistake, and then make blanket nonsensical statements like "don't use Switch"... when from a coding standpoint switch is one of the most efficient structures there is. Certainly more efficient and cleaner syntax than objects for nothing, methods for nothing, method lookups, etc, etc, etc.

You can see this in tools like "linters" which are almost always making blanket pedantic ignorant judgements of code. Concepts that have nothing to do with code quality and everything to do with the petty whims of whoever made the linter.

Take the card-stacked example in your "Else statements" section. The more you reduce the code functionality the easier it is to think "Well I should never use else"

But what if your conditions are NOT returning and just setting up for later operations. If you are going to return your result, well that's fine and dandy. But if the result requires further use, relying on "return" instead of "else" isn't even viable!

I mean look at your code, if we continue that same logic we could say "well there's no reason to ever use "if" either!" since your final result could simply have been written as:

return something;

…since we have loose typecasting!

You've simplified it down to the point the result is card stacked. That said, YES, if you're doing a return for the love of Christmas don't “else”. That does NOT eliminate the purpose of "else".

Same with switch. Maybe it's because I learned machine language when most members here on medium weren't even a twinkle in their father's eye, maybe it's because my first “real” HLL was Pascal, maybe it's that decade working in Ada, maybe I'm just an ***hole... but switch is a simple easy, effective mechanism that programmers in REAL languages have used forever without problem. That this current crop of crybaby JavaScript fanboys seem to get their panties in a knot over it's use, much less useful constructs like drop-through to me just means their education is deficient, not that "switch" should be avoided at all costs.

Gah, the next developer who loses their **** just because I actually leverage drop-through — for multi-casing or code reduction — is getting my size nine so far up their backside they’ll be flossing with my laces for a week!

But again, your usage example is card stacked since you've got nearly a binary result. Switch should be used when the actions are radically different, not when they are uniform!

Your example is a great one for the case where yes, an object lookup makes sense when you need no case validations. (such as "default" not being a valid status). But that falls apart in cases where you might be doing something like parsing an object input of a attributes to be assigned to a HTMLElement type object in something like a DOM "maker" function.

Take for example how case can be leveraged in a DOM maker. The whole reason to work on the DOM is to make it faster, so why bang the brakes on performance and go nutters on function calls when switch can not only get the job done, it can do so faster.

function make(selector, commands, forceParent = false) {



selector = splitSelector(selector);

var e = document.createElement(selector.tagName || 'div');

if (selector.id) e.id = selector.id;

if (selector.class) e.class = selector.class;

if (

selector.special &&

tagSpecials[e.tagName]

) e[tagSpecials[e.tagName]] = selectors.special;

if (selector.textContent) e.textContent = selector.textContent;



if (forceParent) forceParent.appendChild(e); for (var [attr, value] of commands) {



switch (attr) {



case 'after':

value.parentNode.insertBefore(e, value.nextSibling);

continue;



case 'before':

value.parentNode.insertBefore(e, value);

continue;



case 'first':

value.insertBefore(e, value.firstChild);

continue;



case 'last':

value.appendChild(e);

continue;



case 'content':

if (value instanceof Array) make(value[0], value[1], e);

} else e.appendChild(

value instanceof Node ? value : d.createTextNode(value)

);

continue;



case 'style':

for (var [selector, style] of value) e.style[selector] = style;

continue;



case 'className':

// use className not "class" as it's a reserved word.

attr = 'class';

// YES, DROP-THROUGH! NO continue or break



} // switch (attr)



// remember, setAttribute only handles strings

if (

value instanceof Array ||

"function" == typeof value ||

"object" == typeof value

) e[attr] = value;

// but many properties won't update you don't setAttribute

else e.setAttribute(attr, value);



} // for commands



return e;



} // make // notice how "continue" instead of "break" means we don't need "default"

The type of thing where many ignorant fools out there would piss and moan about functions that "do too much" not realizing that C code nearly identical to it is what makes the browser and scripting engines even work in the first blasted place!

Laughably, that’s a clean-room reimplementation of what one of react’s functions does internally, just with a few extra bells and whistles.

Anyone who doesn’t understand the above code PROBABLY shouldn’t be coding JS that manipulates the DOM.

There are a lot of times where you may want multiple results to do the same operation separate from the default. That’s when SWITCH and “drop-through” really shines:

switch (something) {

case 1:

case 2:

case 3:

processAction();

continue;

case 4:

console.log('finalizing');

case 5:

if (updateAction()) console.log('finalized');

saveAction();

// possibly do a whole bunch more here

break;

default:

return unknownAction();

}

Implementing that with an object property lookup is likely to suck. Oh noes, those evil drop-throughs! BARF! Seriously if that’s “difficult to understand or follow” code, just back away from the keyboard and take up something a bit less detail oriented like macramé!

Same for function arguments -- "wah wah, I'm too lazy to look at the function's declaration" is no reason to not avail oneself of one of the most natural mechanisms in the majority of programming languages. The kneejerk reaction should be "where is "doSomething" declared", NOT "wah wah, I'z two lazy too figgur tis oot"..

Adding the overhead of object creation, the extra memory allocation involved, in that, and the extra code is often a really BAD answer.

Sometimes though it's a good answer if that data is ALREADY in an object or indeed the data is complex enough to warrant it; such as when the data itself changes what parameters exist and/or are passed.

Four parameters two of which seem to be boolean? Not so much.

And really, if a broken (did we mention that's broken) if statement with only two comparisons is "hard to read" please, just back away from the keyboard and flip burgers for a living. If you think moving the processing into a "variable for nothing" wasting memory and processing time is a "good thing" I shudder to think what wrecks your code are.

All to do what:

if ( // has retired?

(person.age >= 65) &&

(!person.isEmployed)

) {

\\ ...

}

… can provide as much if not MORE clarity for, without wasting memory and processing time on a "variable for nothing" requiring a malloc() and free() of one of JavaScript's bloated objects pretending to be variables.

But such horrifically bad practices being promoted as the greatest thing seems to be part and parcel of the "new wave" of programmers out there.

People slop everything onto one line for no reason, then throw even more code at stuff for Christmas only knows what, resulting in harder to read harder to maintain code, then run around slapping each-other on the back over how much "easer" and “modern” it all is. Makes me want to vomit.

I think a lot of that though stems from how I learned low level programming FIRST, and programmed for near on two decades before I ever once had to deal with the train wreck of bug inducing trash that is C syntax. It gives me a radically different perspective where I actually THINK “what’s the overhead of calling another function going to do” and “do I need all these variables given what memory thrashing it’s going to create in both creation and garbage collection?”

Concepts most modern dev’s seem unaware of which is part of why they seem to have never heard one of the first lessons I learned in programming some four decades ago.

The less code you use, the less there is to break!

Something all these extra functions, objects, and variables for NOTHING seem to be the antithesis of! Just like how many of these new “operators” and idiocy like “arrow functions” seem to piss on the very notion of code clarity. I’ll never understand how people think adding functions or variables they don’t need aids in “code clarity”.

But what do I know? I say the exact same thing of C syntax; since how dare we use words like “and”, “or”, or “not” in our code. You get some of this new junk like “=>” , “…”, etc, etc, and I swear JavaScript fanboys won’t be happy until the language is an obfuscated mess that looks like brainf***.

Though to be fair, I’m still not convinced this is a joke:

https://www.gnu.org/fun/jokes/unix-hoax.html

So YMMV.