Почему JavaScript обрабатывает число как восьмеричное, если оно имеет начальный нуль

var x = 010;
console.log(x); //8

Двигатель JS преобразует число x в восьмеричное число. Почему так происходит? Как я могу предотвратить это?

Ответ 1

Я думаю, что мой ответ здесь отвечает на вопрос, но вопрос не совсем дубликат, поэтому я прилагаю копию своего ответа.

история

Проблема в том, что десятичные целочисленные литералы не могут иметь начальные нули:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits(opt)

Однако ECMAScript 3 позволил (в качестве необязательного расширения) проанализировать литералы с ведущими нулями в базе 8:

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

Но ECMAScript 5 запрещает делать это в строгом режиме:

Соответствующая реализация при обработке кода строгого режима (см. 10.1.1) не должна расширять синтаксис NumericLiteral для включения OctalIntegerLiteral, как описано в B.1.1.

ECMAScript 6 представляет BinaryIntegerLiteral и OctalIntegerLiteral, так что теперь у нас есть более связные литералы:

  • BinaryIntegerLiteral, с префиксом 0b или 0B.
  • OctalIntegerLiteral, с префиксом 0o или 0O.
  • HexIntegerLiteral, с префиксом 0x или 0X.

Старое расширение OctalIntegerLiteral было переименовано в LegacyOctalIntegerLiteral, что по-прежнему разрешено в нестрогом режиме.

Заключение

Поэтому, если вы хотите проанализировать число в базе 8, используйте префиксы 0o или 0O (не поддерживаются старыми браузерами) или используйте parseInt.

И если вы хотите быть уверены, что ваши числа будут проанализированы в базе 10, удалите начальные нули или используйте parseInt.

Примеры

  • 010
    • В строгом режиме (требуется ECMAScript 5) он выбрасывает.
    • В нестрогом режиме он может выдать или вернуть 8 (зависит от реализации).
  • 0o10, 0O10
    • До ECMAScript 6 они кидают.
    • В ECMAScript 6 они возвращают 8.
  • parseInt('010', 8)
    • Возвращает 8.
  • parseInt('010', 10)
    • Возвращает 10.

Ответ 2

Это потому, что некоторые JavaScript-движки интерпретируют ведущие нули как восьмеричные литералы. Он определен в приложении спецификации ECMAScript.

Однако в строгом режиме соответствующие реализации не должны реализовывать это - см. спецификацию ECMAScript:

Соответствующая реализация при обработке строгого режима (см. 10.1.1), не должен расширять синтаксис NumericLiteral, чтобы включить OctalIntegerLiteral, как описано в B.1.1.

Из-за этой двусмысленности лучше не использовать начальные нули.

Ответ 3

JS обрабатывает числа с ведущими нулями как восьмеричные, только если они действительны восьмеричные, если нет, то он обрабатывает их как десятичные. Для предотвращения этого не используйте начальные нули в исходном коде

console.log(010, 10, +"010")

if (021 < 019) console.log('Paradox');