Try this:

```
var num = 040;
console.log(num); // 32
```

Since when is 40 = 32?

With a leading zero, the number is interpreted as octal and `4 * 8 = 32`

.

It's being treated as octal (base 8) because of the leading `0`

, just like a leading `0x`

would make it hex (base 16). This has a long and tortured history and is no longer how octal numbers are written in modern JavaScript. In modern JavaScript using strict mode, the "legacy" octal format is a syntax error; octal numbers are written with an `0o`

prefix.

Early on (in the initial language from Netscape and the first and second ECMAScript specifications), a leading `0`

on a numeric literal officially meant *octal* (base 8), just as a leading `0x`

means hexadecimal (base 16):

```
OctalIntegerLiteral ::
0 OctalDigit
OctalIntegerLiteral OctalDigit
```

E.g., `10`

, `012`

, and `0xA`

were all ways of writing the decimal number ten. This is in keeping with some other languages with syntax similar to JavaScript (C, C++, Java, ...), but it's highly confusing.

As of ECMAScript 3, that form of octal literal was downgraded to an optional extension, and decimal integer literals were changed so that they can't have leading zeros (unless the implementation includes the extension):

```
DecimalIntegerLiteral ::
0
NonZeroDigit DecimalDigits(opt)
```

But ECMAScript 5 forbade doing that in strict-mode:

A conforming implementation, when processing strict mode code (see 10.1.1), must not extend the syntax of

NumericLiteralto includeOctalIntegerLiteralas described in B.1.1.

ECMAScript 6 (ECMAScript 2015) introduces *BinaryIntegerLiteral* and *OctalIntegerLiteral*, so now we have more coherent literals:

*BinaryIntegerLiteral*, prefixed with`0b`

or`0B`

.*OctalIntegerLiteral*, prefixed with`0o`

or`0O`

.*HexIntegerLiteral*, prefixed with`0x`

or`0X`

.

The old *OctalIntegerLiteral* extension has been renamed to *LegacyOctalIntegerLiteral*, which is still allowed in non-strict mode.

**Conclusion**

Therefore, if you want to parse a number in base 8, use the `0o`

or `0O`

prefixes (not supported by old browsers), or use `parseInt`

.

And if you want to be sure your numbers will be parsed in base 10, remove leading zeros, or use `parseInt`

.

**Examples**

`010`

- In strict mode (requires ECMAScript 5), it's a syntax error.
- In non-strict mode, it may be a syntax error or return
`8`

(implementation dependent).

`0o10`

,`0O10`

- Before ECMAScript 6, they're syntax errors.
- In ECMAScript 6, they return
`8`

.

`parseInt('010', 8)`

- It returns
`8`

.

- It returns
`parseInt('010', 10)`

- It returns
`10`

.

- It returns

If you're interested, you can find the current living specification here, and historical versions here.

Because the `0`

prefix indicates an octal number (base 8).

©2020 All rights reserved.