There are a lot of beginners out there and even experienced developers who are confused about what it means for something to be truthy in Javascript. There’s also an assumption that many people never go out of their way to validate, where they think loose equality (==) is the same thing as truthiness.
Truthiness makes some level of intuitive sense to most people who deal with it. If you show someone the following code snippet, chances are they will have a vague understanding of what’s going on. Even if they aren’t Javascript developers.
Javascript
if ("test") {console.log("This will run")}if ("") {console.log("This won't run!")}
But the explanation that is given is often muddled with misconceptions about how comparisons and equality works in Javascript.
Xetera
So why do you think the if statement works if the string isn't empty?
Tzuyu
Because a non-empty string is truthy, right?
Xetera
Yeah, do you know what that means?
Tzuyu
Yeah
I think so
Xetera
Have you actually tried that?
Tzuyu
no
Tzuyu
wait wtf
Dubu
lmao
Truthiness
It might be a good idea to take a step back and establish what it means for something to be truthy first. Many people get a feeling for how this works but don’t actually dive into the details. In simple terms, truthiness is just what you get when you throw the variable in question into the Boolean() function.
Javascript
Boolean("") // falseBoolean("memes") // true
so any time you’re calling an if statement, what that if statement is actually doing is this:
Javascript
if (Boolean(x)) {}
The Ecma-262 spec defines a function that it refers to as ToBoolean
, and all implicit boolean conversions including the explicit Boolean()
behave according to it with the following lookup table.
Argument Type | Result |
---|---|
Undefined | Return false. |
Null | Return false. |
Boolean | Return argument. |
Number | If argument is +0đť”˝, -0đť”˝, or NaN, return false; otherwise return true. |
String | If argument is the empty String (its length is 0), return false; otherwise return true. |
Symbol | Return true. |
BigInt | If argument is 0ℤ, return false; otherwise return true. |
Object | Return true. |
This might come as a surprise to some. What is truthy and what is falsy is clearly defined for each data type and has nothing to do with equality. This is the reason why you might expect arrays inside if statements to behave the way they do.
Javascript
if ([]) {console.log("This is always true")}
An array is an object which is always true regardless of its contents. If you’re a python developer, this is likely confusing since python’s lists implement bool differently and empty lists are considered falsy just like empty strings.
So if truthiness isn’t based on ==
, what’s going on with loose equality?
Loose Equality
Javascript has this quality where it tries to make guesses for you about what you’re trying to do and change the data it receives in order to have things make sense. This is called coercion
and it isn’t necessarily always bad. The examples above are a fairly common way for Javascript devs to do if statements. Checking things like
Javascript
if (array.length) {console.log("This array has a length of at least 1")}
to make sure an array isn’t empty. The same coercion happens when using the loose comparison operator ==
, so why is plopping things inside if
statements acceptable but using ==
isn’t?
For one, ToBoolean
is a unary function, meaning it has a single input and so it’s a lot easier to wrap one’s head around than ==
which is a binary operator with 2 inputs. But another reason is because loose comparison is actually a recursive operator…
That’s right, loose comparison is implemented recursively. Meaning that comparison between two non-matching data types could recurse as much as 4 times, converting the inputs in each iteration into a different one and re-running the equality check.
There’s an extremely useful website on this topic that visually shows exactly how this process works between different kinds of inputs.
But basically in summary, equality is defined separately from truthiness. The only similarity they share is that truthiness is a form of coercion and loose equality can make use of a similar type of coercion although equality itself does not rely on the concept of truthiness.