Perché JavaScript considera un numero come ottale se ha uno zero iniziale

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

Il motore JS converte il numero da x a numero ottale. Perché succede? Come posso impedirlo?

Penso che la mia risposta qui risponda alla domanda, ma la domanda non è esattamente un duplicato, quindi includo una copia della mia risposta.

Storia

Il problema è che i letterali interi decimali non possono avere zeri iniziali:

 DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits(opt) 

Tuttavia, ECMAScript 3 consentiva (come estensione opzionale) di analizzare i valori letterali con gli zeri iniziali nella base 8:

 OctalIntegerLiteral :: 0 OctalDigit OctalIntegerLiteral OctalDigit 

Ma ECMAScript 5 proibiva di farlo in modalità rigorosa:

Un’implementazione conforms, quando si elabora il codice di modalità rigoroso (vedere 10.1.1) , non deve estendere la syntax di NumericLiteral per includere OctalIntegerLiteral come descritto in B.1.1 .

ECMAScript 6 introduce BinaryIntegerLiteral e OctalIntegerLiteral , quindi ora abbiamo letterali più coerenti:

  • BinaryIntegerLiteral , con prefisso 0b o 0B .
  • OctalIntegerLiteral , con prefisso 0o o 0O .
  • HexIntegerLiteral , con prefisso 0x o 0X .

La vecchia estensione OctalIntegerLiteral è stata rinominata in LegacyOctalIntegerLiteral , che è ancora consentita in modalità non rigida.

Conclusione

Pertanto, se si desidera analizzare un numero nella base 8, utilizzare i prefissi 0o o 0o O (non supportati dai vecchi browser) o utilizzare parseInt .

E se vuoi essere sicuro che i tuoi numeri saranno analizzati in base 10, rimuovi gli zeri parseInt o usa parseInt .

Esempi

  • 010
    • In modalità rigorosa (richiede ECMAScript 5), genera.
    • In modalità non rigida, può lanciare o restituire 8 (dipende dall’implementazione).
  • 0o10 , 0O10
    • Prima di ECMAScript 6, lanciano.
    • In ECMAScript 6, restituiscono 8 .
  • parseInt('010', 8)
    • Restituisce 8 .
  • parseInt('010', 10)
    • Restituisce 10 .

È perché alcuni motori JavaScript interpretano gli zeri iniziali come numeri letterali ottali. È definito in un’appendice delle specifiche ECMAScript .

Tuttavia, in modalità rigorosa, le implementazioni conformi non devono implementarlo, consultare di nuovo le specifiche ECMAScript :

Un’implementazione conforms, quando si elabora il codice di modalità rigoroso (vedere 10.1.1), non deve estendere la syntax di NumericLiteral per includere OctalIntegerLiteral come descritto in B.1.1.

A causa di questa ambiguità, è meglio non utilizzare gli zeri iniziali.