Explicit is better than tricks

Explicit is better than tricks

ยท

5 min read

When writing code, it is always better to be as explicit as possible instead of going for tricks. This concept is best explained by examples so let's get right into it.

The double bang !! (logical NOT)

This one is by far the most common "trick" in the JavaScript world. So much so that it is actually taught to developers as they learn about logical operators in JavaScript and can be found in Mozilla's official documentation (MDN). If you wish to obtain a primitive boolean (true or false) from a non-boolean entity, you can use the logical NOT operator as follows:

const primitiveBoolean = !!notABoolean;

If notABoolean is truthy in the example above, primitiveBoolean will contain the value true and if it is falsy, primitiveBoolean will be false.

You can get the same results by using the Boolean() function and get a much more readable version of the code.

const primitiveBoolean = Boolean(notABoolean);

Does the double bang way provide any benefit? The correct answer is no, but it does carry the disadvantage of making your code less readable. This trick (like many others) works because of JavaScript's type coercion. Let's look at the spec to see how the logical NOT operator (!) works.

1.png

Specification for logical NOT operator

As can be seen, after the expression is evaluated and a final value is obtained, this final value is passed through an algorithm to get the final value's boolean equivalent. This algorithm is represented by ToBoolean() in the spec and is basically just a series of conditions to determine the boolean equivalent of a value (you can see the exact steps by clicking on ToBoolean on the spec's page). Once this is done, next step is what the NOT operator is supposed to do: return false if the evaluated value is true and true otherwise. The second NOT operator then inverts this value to finally give the correct result (and we end up with the double bang !!).

Now let's see how the Boolean() function works.

2.png

Specification for Boolean function

So when Boolean() is called as a function, as opposed to a constructor (i.e. with the new keyword), it performs a simple type conversion. This type conversion is done using the same algorithm, ToBoolean(), discussed above.

In both cases, your code is performing the same task behind the scenes. If anything, the double bang trick has an extra step of inverting the value obtained by the first operation. While using Boolean() results in a much more elegant and readable code.

The unary + operator

Wish to convert a string representation of a number to an actual number? Just precede it with a + like so:

const myData = +"123";
console.log(typeof myData); // output: "number"

This gives us even more obscure code than the double bang trick discussed above. Still, this might prove to be controversial as even the MDN docs say that this is the "preferred" method to convert a string to a number. Let's look at the alternative:

const myData = Number("123");
console.log(typeof myData); // output: "number"

Just as we had used Boolean() as a function to get a primitive boolean value, we have used Number() as a function here to convert the string to a number. The details behind the scenes here are exactly the same as before except the fact that instead of ToBoolean, the algorithm used for type conversion is called ToNumber in this case.

Specification for unary + operator

Specification for Number function

The MDN docs say that using the unary + operator is the fastest method but the specs tell us a different story. Both + and Number() use the exact same algorithm to do the type conversion but the latter results in a much more readable code.

The magic numbers

This one isn't related to type conversion but is seen relatively frequently. Magic numbers are the use of numbers directly in your code. It is more preferable to declare a well-named variable and assign it the desired value than to use the number directly.

if (password.length < 6) {
  throw new Error("Password must be more than 5 characters long");
}

Considering the code above, a much better approach would be:

const MIN_PASSWORD_LENGTH = 6;

if (password.length < MIN_PASSWORD_LENGTH) {
  throw new Error(`Password must be more than ${MIN_PASSWORD_LENGTH - 1} characters long`);
}

The first and obvious advantage here is that the code is now much more readable. Another potential advantage would be in the case where the same constraint is utilized in multiple places (which happens fairly often). If the constraint later changes, you'll only have to update it at one location.

If there is a direct number in your code, strongly consider declaring a constant and using it instead. Most of the times this will be the correct approach. Although there are some edge cases where using the number directly might be the preferable.

if (transactions.length > 0) {
  // show transactions
} else {
  // show msg: "No transactions"
}

The above code is perfectly readable and there seems to be no reason to declare a separate variable for the value 0.

Conclusion

When writing code, readability should be a priority. The tricks/shortcuts usually add no benefit, performance or otherwise, and make the code considerably less readable. So, always go for a more explicit option.


๐Ÿ‘‰๐Ÿป Follow me on twitter: click here

๐Ÿ‘‡๐Ÿป Subscribe to my newsletter


ย