All topics
ES6+beginner

Numeric Separators and New Number Methods

Underscore separators for readable large numeric literals, plus static Number methods that avoid relying on global functions with looser coercion.

Small readability and correctness improvements to numbers.

Numeric separators are like writing '1,000,000' instead of '1000000' on a whiteboard — purely for the human reading it. The strict Number methods are a bouncer who checks you're holding a real ticket before considering whether it's valid, rather than a lenient doorman who'll accept a scribbled note and try to interpret it.

Key Concepts

1
Numeric separators.
    1_000_000        instead of 1000000
    0b1010_0001      binary, grouped
    0xFF_EC_DE       hex
    1_000.000_1
2
Purely visual — the underscores are ignored. They are not allowed at the start, at the end, or next to the decimal point, and they cannot appear in a string that is later converted.
3
The Number statics replace the global functions.
    Number.isNaN(x)          vs  isNaN(x)
    Number.isFinite(x)       vs  isFinite(x)
    Number.isInteger(x)
    Number.isSafeInteger(x)
    Number.parseFloat(s)     same as the global
    Number.parseInt(s, 10)   same as the global
Number
4
The first two differ from their global versions, and that is the point:
5
    isNaN('abc')             // true  -- coerces first
    Number.isNaN('abc')      // false -- it is a string, not NaN
6
    isFinite('42')           // true  -- coerced
    Number.isFinite('42')    // false
7
The globals convert their argument before testing, so they answer a different question. The Number versions test the value as given, which is almost always what was meant.
Number
8
parseInt always takes a radix.
    parseInt('08')           // 8 in modern engines
    parseInt('0x10')         // 16 -- hex detected
    parseInt('10', 2)        // 2  -- explicit binary
parseInt
9
Omitting it relies on inference, which has changed over time and still surprises with hex-looking input.
10
The safe integer constants.
    Number.MAX_SAFE_INTEGER    9007199254740991
    Number.MIN_SAFE_INTEGER
    Number.EPSILON             the smallest meaningful difference
11
    Math.abs(a - b) < Number.EPSILON   // compare floats sensibly
12
And the conversion distinction worth knowing.
    Number('42abc')      // NaN -- the whole string, or nothing
    parseInt('42abc')    // 42  -- reads as far as it can
13
Number() is stricter and is usually what you want for validating input. parseInt is for extracting a number from text that legitimately contains more, such as '20px'.
Number()parseInt'20px'
14
What the interviewer is probing.1. "What problem do numeric separators solve?" Probing: readability. Stalls: "Nothing." Moves up: underscores in a literal make large constants readable — 1_000_000 — with no runtime effect.
15
2. "Why use Number.parseFloat over the global?" Probing: the reason. Stalls: "They differ." Moves up: they are identical; the namespaced version exists so the globals can eventually be deprecated.
16
3. "What does Number.isInteger do that a modulo check does not?" Probing: the edge cases. Stalls: "The same." Moves up: it returns false for non-numbers without coercion, where a modulo check would coerce a string.
17
4. "How do you compare floats safely?" Probing: the epsilon. Stalls: "With ===." Moves up: compare the absolute difference against Number.EPSILON, or work in integers of the smallest unit.