Number Literal Extensions

Prior to ES5, number literals looked like the following — the octal form was not officially specified, only allowed as an extension that browsers had come to de facto agreement on:

  1. var dec = 42,
  2. oct = 052,
  3. hex = 0x2a;

Note: Though you are specifying a number in different bases, the number’s mathematic value is what is stored, and the default output interpretation is always base-10. The three variables in the previous snippet all have the 42 value stored in them.

To further illustrate that 052 was a nonstandard form extension, consider:

  1. Number( "42" ); // 42
  2. Number( "052" ); // 52
  3. Number( "0x2a" ); // 42

ES5 continued to permit the browser-extended octal form (including such inconsistencies), except that in strict mode, the octal literal (052) form is disallowed. This restriction was done mainly because many developers had the habit (from other languages) of seemingly innocuously prefixing otherwise base-10 numbers with 0‘s for code alignment purposes, and then running into the accidental fact that they’d changed the number value entirely!

ES6 continues the legacy of changes/variations to how number literals outside base-10 numbers can be represented. There’s now an official octal form, an amended hexadecimal form, and a brand-new binary form. For web compatibility reasons, the old octal 052 form will continue to be legal (though unspecified) in non-strict mode, but should really never be used anymore.

Here are the new ES6 number literal forms:

  1. var dec = 42,
  2. oct = 0o52, // or `0O52` :(
  3. hex = 0x2a, // or `0X2a` :/
  4. bin = 0b101010; // or `0B101010` :/

The only decimal form allowed is base-10. Octal, hexadecimal, and binary are all integer forms.

And the string representations of these forms are all able to be coerced/converted to their number equivalent:

  1. Number( "42" ); // 42
  2. Number( "0o52" ); // 42
  3. Number( "0x2a" ); // 42
  4. Number( "0b101010" ); // 42

Though not strictly new to ES6, it’s a little-known fact that you can actually go the opposite direction of conversion (well, sort of):

  1. var a = 42;
  2. a.toString(); // "42" -- also `a.toString( 10 )`
  3. a.toString( 8 ); // "52"
  4. a.toString( 16 ); // "2a"
  5. a.toString( 2 ); // "101010"

In fact, you can represent a number this way in any base from 2 to 36, though it’d be rare that you’d go outside the standard bases: 2, 8, 10, and 16.