JavaScript variables are loosely/dynamically typed and the language doesn’t care how a value is declared or changed.

2017.08.22: This article has been updated to reflect the current state of the JavaScript ecosystem.

let x ; x = 1 ; x = '1' ; x = [ 1 ] ;

Seemingly different values equate to true when compared with == (loose or abstract equality) because JavaScript (effectively) converts each to a string representation before comparison:

1 == '1' ; 1 == [ 1 ] ; '1' == [ 1 ] ;

A more obvious false result occurs when comparing with === (strict equality) because the type is considered:

1 === '1' ; 1 === [ 1 ] ; '1' === [ 1 ] ;

Internally, JavaScript sets a value to one of six primitive data types:

Undefined (a variable with no defined value)

Null (a single null value)

Boolean (true or false)

Number (this includes Infinity and NaN – not a number!)

and – not a number!) String (textual data)

Symbol (a unique and immutable primitive new to ES6/2015)

Everything else is an Object — including arrays.

Truthy and Falsy

As well as a type, each value also has an inherent boolean value, generally known as either truthy or falsy. Some of the rules are a little bizarre so understanding the concepts and effect on comparison helps when debugging JavaScript applications.

The following values are always falsy:

false

0 (zero)

(zero) '' or "" (empty string)

or (empty string) null

undefined

NaN

Everything else is truthy. That includes:

'0' (a string containing a single zero)

(a string containing a single zero) 'false' (a string containing the text “false”)

(a string containing the text “false”) [] (an empty array)

(an empty array) {} (an empty object)

(an empty object) function(){} (an “empty” function)

A single value can therefore be used within conditions, e.g.

if ( value ) { } else { }

Loose Equality Comparisons With ==

Unexpected situations can occur when comparing truthy and falsy values using the == loose equality:

== true false 0 '' null undefined NaN Infinity [] {} true true false false false false false false false false false false false true true true false false false false true false 0 false true true true false false false false true false '' false true true true false false false false true false null false false false false true true false false false false undefined false false false false true true false false false false NaN false false false false false false false false false false Infinity false false false false false false false true false false [] false true true true false false false false false false {} false false false false false false false false false false

The rules:

false , zero and empty strings are all equivalent. null and undefined are equivalent to themselves and each other but nothing else. NaN is not equivalent to anything – including another NaN ! Infinity is truthy – but cannot be compared to true or false ! An empty array is truthy – yet comparing with true is false and comparing with false is true ?!

Examples:

false == 0 ; 0 == '' ; null == undefined ; [ ] == false ; ! ! [ 0 ] == true ; false == null ; NaN == NaN ; Infinity == true ; [ ] == true ; [ 0 ] == true ;

Strict Equality Comparisons With ===

The situation is clearer when using a strict comparison because the value types must match:

=== true false 0 '' null undefined NaN Infinity [] {} true true false false false false false false false false false false false true false false false false false false false false 0 false false true false false false false false false false '' false false false true false false false false false false null false false false false true false false false false false undefined false false false false false true false false false false NaN false false false false false false false false false false Infinity false false false false false false false true false false [] false false false false false false false false false false {} false false false false false false false false false false

The only exception is NaN which remains stubbornly inequivalent to everything.

Recommendations

Truthy and falsy values can catch out the most experienced developers. Those new to programming or migrating from other languages have no chance! Fortunately, there are simple steps to catch the most difficult-to-spot errors when handling truthy and falsy variables:

1. Avoid direct comparisons

It’s rarely necessary to compare two truthy and falsy values when a single value will always equate to true or false:

if ( x == false ) if ( ! x )

2. Use === strict equality

Use a === strict equality (or !== strict inequality) comparisons to compare values and avoid type conversion issues:

if ( x == y ) if ( x === y )

3. Convert to real Boolean values where necessary

Any value can be converted to a real Boolean value using a double-negative !! to be absolutely certain a false is generated only by false , 0 , "" , null , undefined and NaN :

if ( x === y ) if ( ! ! x === ! ! y )

Conclusion

Truthy and falsy values allow you to write terse JavaScript conditions and ternary operators. However, always consider the edge cases. A rogue empty array or NaN variable could lead to many hours of debugging grief!