4 min read

Truthiness is not loose equality

Banner image

if(x) and x == true are entirely different concepts.


Guide
Published

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.

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

like if you were comparing "test" == true it would be truthy

2

Xetera

Have you actually tried that?

Tzuyu

no

Tzuyu

wait wtf

2

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.

Boolean("") // false
Boolean("memes") // true

so any time you’re calling an if statement, what that if statement is actually doing is this:

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 TypeResult
UndefinedReturn false.
NullReturn false.
BooleanReturn argument.
NumberIf argument is +0𝔽, -0𝔽, or NaN, return false; otherwise return true.
StringIf argument is the empty String (its length is 0), return false; otherwise return true.
SymbolReturn true.
BigIntIf argument is 0ℤ, return false; otherwise return true.
ObjectReturn 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.

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

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.