JavaScript types, equality, and coercion

Know the primitive types, why === is safer than ==, and which values count as false.

JavaScript
console.log(typeof 42, typeof "text", typeof true, typeof undefined, typeof null, typeof {}, typeof []);
console.log(0.1 + 0.2 === 0.3, Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON);
console.log("5" + 3, "5" - 3, "5" * "2");
console.log(1 == "1", 1 === "1", null == undefined, null === undefined);
console.log(Boolean(""), Boolean("0"), Boolean(0), Boolean([]), Boolean(NaN));
console.log(NaN === NaN, Number.isNaN(NaN));
Output
number string boolean undefined object object object
false true
53 2 10
true false true false
false true false true false
false true

Explanation

JavaScript has seven primitive types (number, string, boolean, undefined, null, symbol, and bigint) and objects. typeof reports the type of a value, with one famous quirk: typeof null is "object". All numbers are 64-bit floating-point values, which is why 0.1 + 0.2 is not exactly 0.3.

The loose equality operator == converts its operands before comparing, which produces surprising results. The strict operator === compares without conversion and is the default choice. When a value is used as a condition, it is converted to a boolean: false, 0, the empty string, null, undefined, and NaN are falsy, and everything else, including "0" and an empty array, is truthy. NaN is not equal to itself, so use Number.isNaN to test for it.

Explore the dry run
Guided walkthroughReady
1console.log(typeof 42, typeof "text", typeof true, typeof undefined, typeof null, typeof {}, typeof []);
2console.log(0.1 + 0.2 === 0.3, Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON);
3console.log("5" + 3, "5" - 3, "5" * "2");
4console.log(1 == "1", 1 === "1", null == undefined, null === undefined);
5console.log(Boolean(""), Boolean("0"), Boolean(0), Boolean([]), Boolean(NaN));
6console.log(NaN === NaN, Number.isNaN(NaN));

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
typeof null is the historical quirk "object", and arrays are objects too.—
number string boolean undefined object object object
Binary floating point cannot represent 0.1 exactly. Compare with a tolerance.—
number string boolean undefined object object object
false true
+ with a string concatenates, giving "53"; - and * convert the strings to numbers.—
number string boolean undefined object object object
false true
53 2 10
== converts types, === does not. null and undefined are loosely equal but not strictly.—
number string boolean undefined object object object
false true
53 2 10
true false true false
Only the empty string, 0, and NaN are falsy here. The string "0" and the empty array are truthy.—
number string boolean undefined object object object
false true
53 2 10
true false true false
false true false true false
NaN is the only value not equal to itself.—
number string boolean undefined object object object
false true
53 2 10
true false true false
false true false true false
false true

Cost and common mistakes

Each expression is O(1).

  • Avoid == except for the deliberate x == null check, which matches both null and undefined.
  • Number("") is 0 and Number("abc") is NaN. Validate strings before converting them.
  • Whole-number arithmetic is exact only up to 2^53. For larger integers use BigInt.

Try it yourself

What does [] + {} produce?

Reveal answer and reasoning

The string "[object Object]": the empty array becomes an empty string, and the object becomes "[object Object]", so + concatenates them.

Further reading