The sarlacc pit of Javascript
Marko V
Posted on February 25, 2020
One could take this post as a deterrent for continued development with Javscript, and just jump the ship to typescript. If you can, you should. FLY YOU FOOLS!
<insert gandalf meme>
But the topic today, is much like the other days prior, due to linting. But this post goes to the core of javascript and how it works and why C# developers hate it (well not all, some do). For better or worse, this is something that some developers take advantage of and some misuse it out of lack of understanding.
Implicit vs Explicit
Now, some people use implicit checks, to not have to be so verbose with their if-statements or ternary expressions. However, I can only say that with explicit checks, there are no questions as to what you're really checking for or expecting to exist in an object or variable. Not only is this due to using the implicit checking (==) but also due to type coercion that happens in javascript. Just a short example of implicit vs explicit
1 == true -> true
1 === true -> false
the implicit check applies type coercion to check if the value is equal to the other object. So you get a number of 1 to be truthy whilst in explicit check, 1 is clearly just a number with the value of 1 which is not a boolean with the value true.
Type Coercion
Type coercion doesn't happen just in implicit checks, it also happens in if-statements. So that's why you need to be explicit with your statements. If not, you may end up getting an undesired result and a hard to detect bug. Here are some type coercion examples.
if(null) -> false
if(undefined) -> false
if(1) -> true
if(0) -> false
if(2) -> true
if(-1) -> true
if("true") -> true
if("false") -> true
If for instance you want to check if an object has a value or not to protect yourself from it being undefined or null or similar... don't rely on type coercion and just do if (myVar), do an explicit check, even if it feels verbose.
if (typeof myVar !== "undefined" && myVar !== null && myVar !== "")
Now it's clear that you don't want a null, undefined or empty string before executing the block of code in your if-statement.
"Don't compare an object literal with a reference."
And lastly, the very thing that gave me the idea for this post. I saw in a distant piece of code something that made me wonder, if it ever was not truthy because of the implicit check as well as reference compared to an object literal.
var tempArr = [];
// do lots of stuff and potentially add data into tempArr
if (helperFunc() || tempArr != []) {
// do something
}
// more code
Now the inverse implicit check is always going to be true because the value reference in tempArr is not equal to the object literal [] you can test this, by running it in the browser's console just with the simple check of [] == [] or [] === [] which both will say false because they're not referencing the same thing. When you compare objects in JS, you're comparing references. Only with primitives will it try to do value comparisons for.
Now the developer that wrote this if-statement likely meant to check that it's an array and that the array shouldn't be empty before doing work inside that if-block.
So it should say
var tempArr = [];
// do lots of stuff and potentially add data into tempArr
if (helperFunc() || (Array.isArray(tempArr) && tempArr.length > 0)) {
// do something
}
// more code
That makes the statement clearer as to what you're expecting and what criteria you've set for executing that block of code. There's no guess work.
My pet peeve, concerning implicit checks and type coercion, is this kind of statement
if (!!!myvar)
Posted on February 25, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 16, 2024