Long live numeric separators!
Published on 12 May 2020 • 2 min

Cette page est également disponible en français.

Time for the ninth article of our daily series “19 nuggets of vanilla JS.” Today we’re covering a syntax extension for numeric separators that finally brings to JavaScript a comfort item that many other languages have had: the visual splitting of digits to more easily see the components or scale of a number.

The series of 19

Check out surrounding posts from the series:

  1. Inverting two values with destructuring
  2. Easily stripping “blank values” from an array
  3. Long live numeric separators! (this post)
  4. Properly sorting texts
  5. Extracting emojis from a text
  6. …and beyond! (fear not, all 19 are scheduled already)…

The problem

Presented without comment:

const TURNS = 10000000000 // 10 millions? 100? 1 billion? More?
const MASK = 0b10110110 // 8 bits, more, less? What is the first quad?
const FEE = 1500 // $1,500? 15? 1.5? Is there a fixed decimal point?
const FLAT_RATE = 250000 // 250,000 or 2,500 (2,500.00) if in cents?

The solution

Many languages have adopted the _ (underscore) numeric separator in their numeric literals. Do note that the separator has zero impact on the final value, it’s just there to improve the readability of the source code, with roughly the same common-sense constraints other languages provide:

  • Forbidden at the beginning or end of the literal (let n = _10_: that’s a big nope!)
  • Not at the end of the integer part or beginning of the decimal or exponent part of a floating-point literal (let n = 5_._0e_10: that’s three strikes!)
  • No adjacent separators (const FEE = 15__00: nope!)
const TURNS = 10_000_000_000 // 10 billions!
const MASK = 0b1011_0110 // 8 bits, 1st quad = 1011
const FEE = 15_00 // $15.00, in cents
const FLAT_RATE = 2_500_00 // 2,500, in cents

This also works on BigInt literals (a type introduced in ES2020), for which they’re especially useful.

const MASS_OF_EARTH_IN_KG = 6_000_000_000_000_000_000_000_000n


In order Not To Break The Internet™, the Number, parseInt and parseFloat functions do not understand these separators, thereby avoiding a breaking change, which would be a show-stopper for JavaScript.

Right now?!

This became stage 4 in July 2020 and is therefore part of ES2021. But besides Babel transpiling it (you bet, that’s simple), it’s been native since Firefox 70, Chrome 75, Edge 79, Safari 13, Opera 62 and Node 12.5. You also find it in TypeScript.

So I’d say yes, right now 😚