Jason Knight
3 min readJun 1, 2020

--

The “don’t mess with system prototypes” has been something I’ve been arguing with myself about the past year. If one uses a isolating naming convention — like say starting your extensions with a double underscore prefix to indicate being custom methods or properties — and define them as immutable with defineProperty, what exactly is “wrong” with doing it. It sure as shine-ola is more convenient, you can make them both immutable and non-iterable, and you can even make them far more robust using a getter and setter.

I don’t think the problem is so much the idea of attaching things to existing objects as it is the method of accessing Array.Prototype.foo=myFunction; instead of Object.defineProperty(Array.prototype, ‘foo’, { value : myFunction });

The reason to choose switch over if/else should have NOTHING to do with code clarity. It’s about back-end efficiency since you declare the value first. At the machine language level switch/case is many many times more efficicent since you can set up a register with the variable/initial value or a pointer to same, and then only have to read the different comparisons. If/else loads the value or pointer each and every blasted time, increasing the overhead/workload.

… and that’s why when you see

const openingHours = date => {
const weekday = date.getDay();

switch(true) {
case [0,6].includes(weekday):
return "8:00am-12:00pm";

case weekday === 1:
return "Closed";

default:
return "8:00am-20:00pm";
}
}

You’re looking at developer ignorance, incompetence, and ineptitude since it’s not only not operating on the same actual value, it’s performing extra comparisons that shouldn’t be needed.

Likewise drop-through in case is a powerful way to reduce the overall code needed when you have two or more routines that basically do the same thing with one just needing a few lines more than the other. That people advise against doing this is mind-numbingly dumbass and it’s part of why I consider the default settings in most linters to be utter nonsense.

Avoiding implied typecasting is one of those loose recommendations that doesn’t always make sense. I have a LOT of scenarios where testing if there’s a value, or if it exists, or if there’s entries, actually makes more sense. It sure as shine-ola beats the tar out of:

if ((a === 0) || (a === null) || ‘undefined’ === typeof a) || (a === [])) {

It’s particularly useful when using “false on success” since you can just return the error or return nothing. If it’s loose false, there was no error. If it’s loose true if it’s a string you have a fatal error, if it’s an array there were multiple non-fatal errors/warnings.

var errors = isWhatever();
if (errors) {
if (errors instanceof Array) {
for (var i = 0, li, errorTxt; $errorTxt = $errors[i]; i++) {
// handle each errorText here
} else {
// handle errors as errorText
}
}
}

Personally I’d replace most of what you said with espousing the issues, woes, and evils of garbage like innerHTML or document.write. You want bad practices and patterns, few get as bad as ignoring the DOM and slopping markup in from JavaScript.

Though yeah, to blazes with “eval” and anything that performs like it.

--

--

Jason Knight
Jason Knight

Written by Jason Knight

Accessibility and Efficiency Consultant, Web Developer, Musician, and just general pain in the arse

Responses (1)