Have you ever felt unconfident writing "if" conditions? Had you ever written such pieces of code like this:
if (typeof x == "undefined") {
// do some stuff
}
If so, you are welcome to the journey into the weird world of falsy Javascript values!
What falsy values are
In Javascript, we are working usually with four primitive types: numbers, strings, booleans, and objects. For each type, Javascript has special values which help us to express the ideas of the zero element or the absence of a value:
Type | Falsy value |
number | 0 and NaN |
string | "" |
boolean | false |
object | null |
This table would be not full without our favorite value undefined
. We all love the message "undefined is not a function", don't we?
undefined
is a very special value. It has its own type:
console.log(typeof undefined) // will output "undefined"
Uninitialized variables and an object's nonexistent properties will have the value undefined
by default.
Falsy values and if
Falsy values are designed to make the if
-else
clause run the else
part. The code below will output "No" six times:
var xs = [
false,
null,
undefined,
NaN,
0,
""
]
xs.forEach(x => {
if (x) {
console.log('Yes')
} else {
console.log('No')
}
})
So, with if
you can be sure that falsy value will work as you expect. Do you feel now a bit more confident? Great. Because the logic ends here. Now let's talk about really weird things.
Falsy ways of usage falsy values
In all previous snippets, I deliberately omitted any comparison operators like ==
. I will explain why. Let me first modify the previous snippet for it returns "Yes" at the else
part:
var xs = [
false,
null,
undefined,
NaN,
0,
""
]
xs.forEach(x => {
if (!x) {
console.log('No')
} else {
console.log('Yes')
}
})
As you may think, the result should not change. And it is really the same. "No" will be printed 6 times. But let's modify it again a little bit:
var xs = [
false,
null,
undefined,
NaN,
0,
""
]
xs.forEach(x => {
if (x == false) {
console.log('No')
} else {
console.log('Yes')
}
})
This code will output: "No, Yes, Yes, Yes, No, No". But why?
The reason is not so easy to explain... There is a difference between !x
and x == false
. The first operator performs coercion while the second one compares two values.
You may say that this does not have any sense, and, probably, I will agree with you. But we are using Javascript and thus just need to know all these caveats.
What about []
and {}
?
It is interesting that MDN does not mention any of these values in their article about falsy values. Here are some useful facts about them.
{}
by no means behaves as falsy value. But []
may behave as falsy value:
console.log([] == false ? "Yes" : "No") // will output "Yes"
On the other hand, within the if
statement []
is treated as a truthy value, i.e. it makes the statement execute if
part but not the else
part.
if ([]) {
console.log("Yes")
} else {
console.log("No")
}
// The code will output "Yes"
And, of course []
is not equal to another []
because they are two different objects.
And how to live with all this?
Yes, it is not easy to remember all these details. But these tips will help you to avoid mistakes in your code:
null
,undefined
, andNaN
are not equal tofalse
. But you may use them without a comparison operator withinif
statements.NaN
is not equal even to itself. For checking that something is equal toNaN
use ES6 functionNumber.isNan()
.- Remember that
[]
behaves as a falsy value in comparisons. But not within theif
statement. {}
is not a falsy value.
Cheatsheet table
The exhaustive cheatsheet of falsy Javascript values' relationships and behavior can be represented as a table:
The last row assumes that you put the value in the if
statement into its parenthesis as is, without any other values or operators.