JavaScript types, equality, and coercion
Know the primitive types, why === is safer than ==, and which values count as false.
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));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
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));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
| Step / line | What happens | State after step | Output 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.