Em JavaScript, por que isNaN(" ")
avaliar para false
, mas isNaN(" x")
avaliar para true
?
Estou realizando operações numéricas em um campo de entrada de texto, e eu estou verificando se o campo for null
, ""
ou NaN
. Quando alguém digita um punhado de espaços no campo, minha validação falha nos três, e estou confuso sobre o porquê de passar pela isNaN
verificação.
javascript
nan
IVR Avenger
fonte
fonte
"" == false // true
eisNaN(" ") // false
Respostas:
JavaScript interpreta uma cadeia vazia como um 0, que falha no teste isNAN. Você pode usar parseInt na string primeiro, que não converterá a string vazia em 0. O resultado deve falhar é NAN.
fonte
isNaN(arg)
. 1) Converta arg em número, 2) Verifique se esse número é o valor numéricoNaN
. Isso me ajudou a entender melhor.Você pode achar isso surpreendente ou talvez não, mas aqui está um código de teste para mostrar a loucura do mecanismo JavaScript.
então isso significa que
e
mas
Diverta-se :)
fonte
null
,""
e" "
eu mesmo. Obrigado!Para entender melhor, abra o pdf de especificação do Ecma-Script na página 43 "ToNumber aplicado ao tipo de string"
se uma string tiver uma sintaxe numérica, que pode conter qualquer número de caracteres de espaço em branco, poderá ser convertida para o tipo Number. A cadeia vazia é avaliada como 0. Além disso, a cadeia 'Infinito' deve fornecer
fonte
Tente usar:
Ou
fonte
Do
MDN
motivo do problema que você está enfrentandoConvém verificar a resposta abrangente a seguir, que também cobre a comparação de NaN para igualdade.
fonte
Eu acho que é por causa da digitação do Javascript:
' '
é convertido em zero, enquanto que'x'
não é:fonte
Se você deseja implementar uma função isNumber precisa, aqui está uma maneira de fazê-lo a partir do Javascript: The Good Parts, por Douglas Crockford [página 105]
fonte
A resposta não totalmente correta
A resposta altamente votada e aceita de Antonio Haley aqui pressupõe que esse processo passa pela
parseInt
função do JavaScript :Podemos facilmente refutar essa declaração com a string
"123abc"
:Com isso, podemos ver que a
parseInt
função do JavaScript retorna"123abc"
como o número123
, mas suaisNaN
função nos diz que"123abc"
não é um número.A resposta correta
O ECMAScript-262 define como a
isNaN
verificação funciona na seção 18.2.3 .A
ToNumber
função a que se refere também é definida na seção 7.1.3 do ECMAScript-262 . Aqui, somos informados como o JavaScript lida com Strings que são passadas para esta função.O primeiro exemplo dado na pergunta é uma sequência que contém nada além de caracteres de espaço em branco. Esta seção afirma que:
A
" "
sequência de exemplo é, portanto, convertida em+0
, que é um número.A mesma seção também afirma:
Sem citar todas as verificações contidas nessa seção, o
" x"
exemplo dado na pergunta cai na condição acima, pois não pode ser interpretado como aStringNumericLiteral
." x"
é, portanto, convertido paraNaN
.fonte
Não sei por que , mas para contornar o problema, você sempre pode aparar o espaço em branco antes de verificar. Você provavelmente quer fazer isso de qualquer maneira.
fonte
A função
isNaN("")
executa uma coerção do tipo String para NumberO ECMAScript 3-5 define os seguintes valores de retorno para o operador typeof:
Melhor agrupar nosso teste em um corpo de função:
Esta função não tem a intenção de testar o tipo de variável ; em vez disso, testa o valor coagido . Por exemplo, booleanos e strings são coagidos a números, então talvez você queira chamar essa função como
isNumberCoerced()
se não for necessário testar outros tipos além de sequência e número , o seguinte snippet pode ser usado como parte de alguma condição:
fonte
Eu sugiro que você use a seguinte função se você realmente deseja uma verificação adequada se é um número inteiro:
fonte
Isso
isNaN(" ")
é falso faz parte do comportamento confuso daisNaN
função global devido à sua coerção de não números a um tipo numérico.Do MDN :
Observe também que, com o ECMAScript 6, também existe agora o
Number.isNaN
método, que de acordo com o MDN:Infelizmente :
Até o
Number.isNaN
método ECMAScript 6 tem seus próprios problemas, conforme descrito na postagem do blog - Corrigindo o feio problema de JavaScript e ES6 NaN .fonte
A
isNaN
função espera um número como argumento; portanto, argumentos de qualquer outro tipo (no seu caso, uma string) serão convertidos em número antes que a lógica real da função seja executada. (Esteja ciente queNaN
também é um valor do tipo Número!)Btw. isso é comum a todos funções internas - se eles esperam um argumento de um determinado tipo, o argumento real será convertido usando as funções de conversão padrão. Existem conversões padrão entre todos os tipos básicos (bool, string, número, objeto, data, nulo, indefinido).
A conversão padrão para
String
paraNumber
pode ser chamada explícita comNumber()
. Então podemos ver que:Number(" ")
avalia como0
Number(" x")
avalia comoNaN
Diante disso, o resultado da
isNaN
função é completamente lógico!A verdadeira questão é por que a conversão padrão de String para Número funciona da mesma maneira. A conversão de seqüência de caracteres em número realmente pretende converter seqüências numéricas como "123" ou "17.5e4" para números equivalentes. A conversão ignora primeiro o espaço em branco inicial (portanto, "123" é válido) e, em seguida, tenta analisar os demais como um número. Se não for analisável como um número ("x" não é), o resultado será NaN. Mas existe a regra especial explícita de que uma string vazia ou apenas em branco é convertida em 0. Portanto, isso explica a conversão.
Referência: http://www.ecma-international.org/ecma-262/5.1/#sec-9.3.1
fonte
Eu escrevi essa pequena função rápida para ajudar a resolver esse problema.
Ele simplesmente verifica se há caracteres que não são numéricos (0-9), que não são '-' ou '.' E que não são indefinidos, nulos ou vazios e retorna verdadeiro se não houver correspondências. :)
fonte
Como explicado anteriormente, a
isNaN
função coagirá a sequência vazia em um número antes de validá-la, alterando uma sequência vazia para 0 (que é um número válido). No entanto, descobri que aparseInt
função retornaráNaN
ao tentar analisar uma string vazia ou uma string com apenas espaços. Como tal, a seguinte combinação parece estar funcionando bem:if ( isNaN(string) || isNaN(parseInt(string)) ) console.log('Not a number!');
Essa verificação funcionará para números positivos, números negativos e números com um ponto decimal, por isso acredito que abrange todos os casos numéricos comuns.
fonte
NaN
! == "não é um número"NaN
é um valor do tipo de númeroesta é uma definição de isNaN () no ECMAScript
Tente converter qualquer valor para número.
Se você deseja determinar se o valor é
NaN
, tente convertê-lo em um valor numérico primeiro.fonte
Essa função parecia funcionar nos meus testes
fonte
return !(s === "" || s === null || parseInt(s) == 'NaN');
A respeito
fonte
O JavaScript embutido isNaN função, é - como seria de esperar por padrão - um "tipo de operador dinâmico". Portanto, todos os valores que (durante o processo DTC) podem gerar um valor verdadeiro simples | falso como
"", " ", " 000"
, não pode ser NaN.Significando que o argumento fornecido passará primeiro por uma conversão como em:
Explicação:
Na linha superior do corpo da função, estamos (primeiro) tentando converter com êxito o argumento em um objeto numérico. E (segundo), usando o operador de ponto, estamos - para nossa própria conveniência - retirando imediatamente, o valor primitivo do objeto criado.
Na segunda linha, estamos pegando o valor obtido na etapa anterior e a vantagem do fato de NaN não ser igual a nada no universo, nem mesmo a si mesmo, por exemplo:
NaN == NaN >> false
para finalmente compará-lo (por desigualdade) consigo mesmo .Dessa forma, o retorno da função produzirá true somente quando, e somente se, o retorno do argumento fornecido, for uma tentativa falha de conversão para um objeto numérico, ou seja, um número não-numérico; por exemplo, NaN.
isNaNstatic ()
No entanto, para um operador de tipo estático - se necessário e quando necessário - podemos escrever uma função muito mais simples, como:
E evite o DTC completamente para que, se o argumento não for explicitamente um número NaN, ele retornará falso. Portanto, testando contra o seguinte:
isNaNStatic(" x"); // will return false
porque ainda é uma corda.No entanto:
isNaNStatic(1/"x"); // will of course return true.
como será, por exemplo,isNaNStatic(NaN); >> true
.Mas
isNaN
, ao contrário do ,isNaNStatic("NaN"); >> false
porque (o argumento) é uma string comum.ps: A versão estática do isNaN pode ser muito útil em cenários de codificação modernos. E pode muito bem ser uma das principais razões pelas quais dediquei meu tempo postando isso.
Saudações.
fonte
isNAN(<argument>)
é uma função para saber se o argumento fornecido é um número ilegal.isNaN
tipifica os argumentos no tipo Number. Se você deseja verificar se o argumento é numérico ou não? Por favor, use a$.isNumeric()
função no jQuery.Ou seja, isNaN (foo) é equivalente a isNaN (Number (foo)). Ele aceita qualquer string com todos os números como números por razões óbvias. Por ex.
fonte
Eu uso isso
fonte
Ao verificar se determinado valor string com espaços em branco ou
" "
éisNaN
talvez tentar executar a validação de corda, exemplo:// value = "123 " if (value.match(/\s/) || isNaN(value)) { // do something }
fonte