Tente executar o seguinte em JavaScript:
parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!
Acabei de aprender da maneira mais difícil que o JavaScript pensa que o zero inicial indica um número inteiro octal e, como não existe "8"
ou "9"
na base 8, a função retorna zero. Goste ou não, isso ocorre por design .
Quais são as soluções alternativas?
Nota: Por uma questão de integridade, estou prestes a postar uma solução, mas é uma solução que eu odeio, portanto, publique outras / melhores respostas.
Atualizar:
A 5ª edição do padrão JavaScript ( ECMA-262 ) apresenta uma alteração de última hora que elimina esse comportamento. Mozilla tem uma boa redação .
javascript
integer
octal
Portman
fonte
fonte
10
(decimal), a menos que o número a ser analisado seja prefixado0x
, por exemplo0xFF
, nesse caso, o parâmetro base é padronizado como 16. Felizmente, um dia, esse problema será uma memória distante.+'08' === 8
? Verdade! Talvez você realmente preciseparseInt
do seu código real, mas não do acima.Number('08')
0
ouundefined
e o número da string começa com um0
dígito não seguido por umx
ouX
, então a implementação pode, a seu critério, interpretar o número como octal ou decimal. As implementações são incentivadas a interpretar números nesse caso como decimais. " ( minha ênfase)Respostas:
Esta é uma pegadinha Javascript comum com uma solução simples:
Basta especificar a base , ou 'radix', da seguinte forma:
Você também pode usar o Number :
fonte
Se você souber que seu valor estará no intervalo inteiro assinado de 32 bits,
~~x
fará a coisa correta em todos os cenários.Se você procurar o binário not (
~
), a especificação exigirá uma conversão "ToInt32" para o argumento que faz a conversão óbvia para um Int32 e é especificado para coagirNaN
valores a zero.Sim, isso é incrivelmente brincalhão, mas é tão conveniente ...
fonte
Na documentação parseInt , use o argumento radix opcional para especificar a base-10:
Isso me parece pedante, confuso e detalhado (realmente, um argumento extra em cada análise)? Por isso, espero que exista um caminho melhor.
fonte
parseInt
para uso conveniente em expressões funcionais, comomap
em["7","4","09","5"].map(parseInt);
Map
passará o índice do elemento na matriz como o segundo argumento, que será interpretadoparseInt
como a base, a menos que você o agrupe.edit: criar sua própria função, para fazer o que você realmente deseja, é apenas uma opção se você não gosta de adicionar o ", 10" o tempo todo à chamada parseInt (). Tem a desvantagem de ser uma função fora do padrão: mais conveniente para você, se você a usa muito, mas talvez mais confusa para os outros.
fonte
Especifique a base:
fonte
Seria muito impertinente substituir parseInt por uma versão que assume decimal se não tiver um segundo parâmetro? (nota - não testado)
fonte
parseInt("0xFFFFFF") === 16777215
, mas com o seu corte impertinente no lugar ele não funciona maisparseInt("0xFFFFFF") === 0
e para uma boa medida
Link MDN
fonte
Que tal isso para decimal:
fonte
Se você já fez um monte de codificação com parseInt e não deseja adicionar ", 10" a tudo, basta substituir a função para tornar a base 10 o padrão:
Isso pode confundir um leitor posterior, portanto, criar uma função parseInt10 () pode ser mais auto-explicativa. Pessoalmente, prefiro usar uma função simples do que adicionar ", 10" o tempo todo - apenas cria mais oportunidades para erros.
fonte
Esse problema não pode ser replicado no Chrome nem no Firefox (2019) mais recentes.
fonte