21

Набираю в консоли Google Chrome следующий пример (и получаю интересный результат):

for (num = 050; num <= 100; num = num + 1) {
    console.log(num);
}

Печать почему-то начинается от 40. Если ввести вместо этого num = 50, то от 50. В чем разница этих значений для JavaScript, и почему цикл начинается с 40 в первом случае?

Grundy
  • 81,538
Женя Веденин
  • 1,304
  • 1
  • 17
  • 33

2 Answers2

17

Числа, начинающиеся с нуля, считаются восьмеричными, если в них нет цифр больше 7. Ссылка на справку

Грамматику можно посмотреть в спецификации: 11.8.3 Numeric Literals

Grundy
  • 81,538
  • 1
    @ЖеняВеденин, на самом деле нормальный вопрос по не вполне очевидной особенности – Grundy Jan 07 '16 at 18:11
7

В JavaScript определяется целочисленный восьмиричный литерал следующим образом

OctalIntegerLiteral ::
       0o OctalDigits 
       0O OctalDigits
OctalDigits ::
       OctalDigit 
       OctalDigits OctalDigit
OctalDigit :: one of
       0 1 2 3 4 5 6 7

Как можно видеть, литералы, начинающиеся с цифры 0, за которой следует буква строчная o или заглавная O, являются целочисленными восьмиричными литералами.

Проблема в том, что, например, мне не удалось использовать этот литерал в IE 11 независимо от выбранного режима ("USE STRICT").:) В то время как в FireFox 42 данный литерал успешно обрабатывается.

Также в JavaScript определяется так называемый LegacyOctalIntegerLiteral

LegacyOctalIntegerLiteral ::
        0 OctalDigit 
        LegacyOctalIntegerLiteral OctalDigit

В вашем случае используется именно этот литерал.

В спецификации EcmaScript (6 редакция) есть замечание, что

A conforming implementation, when processing strict mode code (see 10.2.1), must not extend, as described in B.1.1, the syntax of NumericLiteral to include LegacyOctalIntegerLiteral, nor extend the syntax of DecimalIntegerLiteral to include NonOctalDecimalIntegerLiteral.

Однако, как обычно, каждый браузер идет своим путем.:)

  • не первым символом O, а 0o или 0O, то есть, вот это: 0o10 восьмиричное число, а вот это o10 может быть обычной переменной, и если она не объявлена, будет Uncaught ReferenceError: o10 is not defined(…) – Grundy Jan 07 '16 at 18:26
  • @Grundy Это я отвлекся и не туда посмотрел, когда писал текст.:) – Vlad from Moscow Jan 07 '16 at 18:35
  • 1
    а где кстати грамматику смотрели? :) – Grundy Jan 07 '16 at 18:36
  • @Grundy Я смотрю ECMA-262. Я отвлекся ранее потому, что почему-то в IE 11 восьмиричный литерал не воспринимается независимо от выбранного режима.:) – Vlad from Moscow Jan 07 '16 at 18:49
  • ага, я в свой ответ добавил ссылку на спецификацию, кстати, как я понял в Edge они починили и этот литерал нормально работает :) – Grundy Jan 07 '16 at 18:50