{ }codelper

Learn › JavaScript

Language-specific · 41

JavaScript equality and truthiness

== vs ===, falsy values, ?? vs ||, numbers that are all doubles, undefined vs null, and what TypeScript catches.

This lesson is for JavaScript · TypeScript.
Other languages do not quietly convert types when comparing.
In Python "5" == 5 is just False (and "5" < 5 is a TypeError), Java and C# refuse to compile it so you convert explicitly, and Craykon's == is false for different types.

JavaScript quietly changes types when it compares values or decides true and false.
The example below reads the text "5" and "0" and shows how == and ===, || and ??, floating-point sums, and undefined and null give different answers.

const [a, b] = require("fs").readFileSync(0, "utf8").trim().split("\n"); console.log(a == 5, a === 5, a === "5");console.log(a + 1, Number(a) + 1);console.log(0 == "", null == undefined, null === undefined); const falsy = [0, "", NaN, null, undefined, false];console.log(falsy.filter(Boolean).length, Boolean("0"), Boolean([])); const count = Number(b);console.log(count || 10, count ?? 10); console.log(0.1 + 0.2, 0.1 + 0.2 === 0.3);console.log(Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON);console.log(Number.MAX_SAFE_INTEGER + 2);console.log(String(2n ** 64n)); const nan = Number("abc");console.log(nan === nan, Number.isNaN(nan)); const user = { name: "Kim" };console.log(user.age, typeof null, user.age ?? "none");
stdin
5
0
stdout
true false true
51 6
true true false
0 true true
10 0
0.30000000000000004 false
true
9007199254740992
18446744073709551616
false true
undefined object none

Key points

  • == converts one side when the types differ.
    That is why "5" == 5, 0 == "" and null == undefined are all true.
  • === also requires the same type.
    The conversion rules are complicated, so rather than memorize them, always use === and !==.
  • + joins text when either side is text.
    "5" + 1 is "51", but "5" - 1 is 4.
    Input is always text, so convert it with Number(...) first.
  • The falsy values are only false, 0, -0, 0n, "", null, undefined and NaN.
    "0" and an empty array [] are truthy (in Python [] is falsy).
  • There are two kinds of 'no value'.
    undefined means nothing was ever put there (a missing property, an argument not passed, the result of a function with no return); null is an "empty" someone set on purpose.
    To check for both, write x == null or x ?? fallback.
  • NaN is not even equal to itself, so NaN === NaN is false; ask with Number.isNaN(x).
    typeof null being "object" is a mistake left over from early JavaScript.

How each language writes it

JavaScriptCompare with ===/!==, give defaults with ??, and turn text into numbers with Number(...).
None of these traps warns you at run time
TypeScriptBlocks some of them at compile time: a == 5 (string vs number) is TS2367, x === NaN is TS2845, and user.age not in the type is TS2339.
Under strict you must check age?: number for undefined before using it.
But types are erased before running, so at run time it is plain JavaScript, and any or as turns the checks off (the example's raw)

Common mistakes

Giving a default with ||

const count = 0;
console.log(count || 10, count ?? 10);

→ 10 0 — || gives the right side whenever the left is falsy, so the valid value 0 turns into 10

Use ??, which gives the right side only for null or undefined.

Comparing floating-point numbers with ===

console.log(0.1 + 0.2);
console.log(0.1 + 0.2 === 0.3);

→ 0.30000000000000004, false — every number is one 64-bit floating-point type (double), so rounding errors appear

Compare the difference, as in Math.abs(x - y) < Number.EPSILON.

Doing math on a very large integer

console.log(Number.MAX_SAFE_INTEGER + 2);

→ 9007199254740992 — integers are exact only up to 2^53 − 1 (9007199254740991), so you do not get ...993

Use BigInt with an n suffix, as in 2n ** 64n.
Mixing it with ordinary numbers, as in 1n + 1, is a TypeError.

How languages differ
Compare with === and give defaults with ??.
== and || produce different answers without any error, such as "5" == 5 being true or 0 turning into 10.

Practice