Число с ведущим нулем в JavaScript - PullRequest
7 голосов
/ 28 июня 2011

Попробуйте это:

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

С каких это пор 40 = 32?

Ответы [ 3 ]

13 голосов
/ 28 июня 2011

При ведущем нуле число интерпретируется как восьмеричное, а 4 * 8 = 32.

8 голосов
/ 06 февраля 2015

TL; DR

Он рассматривается как восьмеричный (основание 8) из-за ведущего 0, так же как ведущий 0x сделает его шестнадцатеричным (основание 16). У этого есть длинная и мучительная история и больше не то, как восьмеричные числа пишутся в современном JavaScript. В современном JavaScript, использующем строгий режим, восьмеричный восьмеричный формат является синтаксической ошибкой; восьмеричные числа пишутся с префиксом 0o.

История

Ранее (на исходном языке из Netscape и в первой и второй спецификациях ECMAScript), ведущий 0 на числовом литерале официально означал восьмеричный (основание 8), так же, как ведущий 0x означает шестнадцатеричное (основание 16):

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

Например, 10, 012 и 0xA были всеми способами записи десятичного числа десять. Это соответствует некоторым другим языкам с синтаксисом, похожим на JavaScript (C, C ++, Java, ...), но это сильно сбивает с толку.

Начиная с ECMAScript 3, эта форма восьмеричного литерала была понижена до необязательного расширения, и десятичные целочисленные литералы были изменены, чтобы они не могли иметь начальные нули (если реализация не включает расширение):

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits(opt)

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

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

ECMAScript 6 (ECMAScript 2015) представляет 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.

Если вам интересно, вы можете найти текущую живую спецификацию здесь и исторические версии здесь .

5 голосов
/ 28 июня 2011

Поскольку префикс 0 указывает восьмеричное число (основание 8).

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