Esse código em JS me fornece um pop-up dizendo "eu acho que nulo é um número", o que acho um pouco perturbador. o que estou perdendo?
if (isNaN(null)) {
alert("null is not a number");
} else {
alert("i think null is a number");
}
Estou usando o Firefox 3. Isso é um bug do navegador?
Outros testes:
console.log(null == NaN); // false
console.log(isNaN("text")); // true
console.log(NaN == "text"); // false
Então, o problema parece não ser uma comparação exata com o NaN?
Edit: Agora que a pergunta foi respondida, limpei minha postagem para ter uma versão melhor para o arquivo. No entanto, isso torna alguns comentários e até algumas respostas um pouco incompreensíveis. Não culpe seus autores. Entre as coisas que mudei estava:
- Removi uma nota dizendo que eu tinha estragado a manchete, revertendo seu significado
- As respostas anteriores mostraram que eu não afirmei com clareza o motivo pelo qual achei o comportamento estranho, então adicionei os exemplos que verificam uma string e fazem uma comparação manual.
javascript
Hanno Fietz
fonte
fonte
Respostas:
Eu acredito que o código está tentando perguntar "é
x
numérico?" com o caso específico aqui dex = null
. A funçãoisNaN()
pode ser usada para responder a essa pergunta, mas semanticamente está se referindo especificamente ao valorNaN
. Da Wikipedia paraNaN
:Na maioria dos casos, achamos que a resposta para "é numérico nulo?" deve ser não. No entanto,
isNaN(null) == false
é semanticamente correto, porquenull
não éNaN
.Aqui está a explicação algorítmica:
A função
isNaN(x)
tenta converter o parâmetro passado em um número 1 (equivalente aNumber(x)
) e depois testa se o valor éNaN
. Se o parâmetro não puder ser convertido em um número,Number(x)
retornaráNaN
2 . Portanto, se a conversão do parâmetrox
em um número resultarNaN
, ele retornará verdadeiro; caso contrário, ele retornará false.Portanto, no caso específico
x = null
,null
é convertido para o número 0 (tente avaliarNumber(null)
e veja se ele retorna 0) eisNaN(0)
retorna false. Uma cadeia de caracteres com apenas dígitos pode ser convertida em um número e isNaN também retorna false. Uma string (por exemplo'abcd'
) que não pode ser convertida em um número fará comisNaN('abcd')
que retorne true, especificamente porqueNumber('abcd')
retornaNaN
.Além desses casos de arestas aparentes, existem as razões numéricas padrão para retornar NaN como 0/0.
Quanto aos testes aparentemente inconsistentes de igualdade mostrados na pergunta, o comportamento de
NaN
é especificado de modo que qualquer comparaçãox == NaN
seja falsa, independentemente do outro operando, incluindo oNaN
próprio 1 .fonte
NaN !== NaN
,. Então, acho que não é totalmente correto dizerNumber('abcd') == NaN
porqueNumber('abcd')
é,NaN
mas não é igual aNaN
. Eu adoro JavaScript.Number('abcd')
éNaN
, mas eu entender que ele testa verdadeiro para a igualdade, o que não é o caso. Eu vou editá-lo.isNaN
e sãoNumber
projetados para se comportar dessa maneira?null
para0
somente (pelo menos neste contexto) ocorre dentro daisNaN()
função, que coagula seu argumento.Acabei de me deparar com esse problema.
Para mim, a melhor maneira de usar isNaN é assim
isNaN(parseInt(myInt))
tomando o exemplo do phyzome de cima,
(Alinhei o resultado de acordo com a entrada, espero que facilite a leitura.)
Isso me parece melhor.
fonte
myInt
= "123d".parseInt
converte "123d" para 123, que falha noisNaN
teste.isNaN(parseInt(str,10)) || isNaN(Number())
. btw - para mim, já que tenho que executarparseInt
para usar o valor numérico da string, permitindo que "123d" seja considerado como número válido. No entanto, vejo a necessidade de detectar esse cenário também.(Meu outro comentário adota uma abordagem prática. Aqui está o lado teórico.)
Olhei para cima do padrão ECMA 262 , que é o que implementa Javascript. Sua especificação para isNan:
A Seção 9.3 especifica o comportamento de
ToNumber
(que não é uma função que pode ser chamada, mas um componente do sistema de conversão de tipos). Para resumir a tabela, certos tipos de entrada podem produzir um NaN. Estes são tipoundefined
, tiponumber
(mas apenas o valorNaN
), qualquer objeto cuja representação primitiva sejaNaN
e qualquer umstring
que não possa ser analisado. Isso deixaundefined
,NaN
,new Number(NaN)
, e a maioria das cordas.Qualquer entrada que produza
NaN
como saída quando passada paraToNumber
produz um atrue
quando alimentadaisNaN
. Comonull
pode ser convertido com sucesso em um número, ele não produztrue
.E é por isso.
fonte
Isso é realmente perturbador. Aqui está uma matriz de valores que eu testei:
Ele avalia (no console do Firebug):
Quando ligo
x.map(isNaN)
(chamar isNaN em cada valor), recebo:Em conclusão,
isNaN
parece bastante inútil! ( Edit : exceto que isNaN é definido apenas sobre Number, caso em que funciona muito bem - apenas com um nome enganador.)Aliás, aqui estão os tipos desses valores:
fonte
Nulo não é NaN, assim como uma string não é NaN. isNaN () apenas teste se você realmente possui o objeto NaN.
fonte
Não sei exatamente quando se trata de JS, mas já vi coisas semelhantes em outras linguagens e geralmente é porque a função está apenas verificando se nulo é exatamente igual a NaN (ou seja, nulo === NaN seria falso). Em outras palavras, não é que ele ache que nulo seja de fato um número, mas sim que nulo não é NaN. Provavelmente, porque ambos são representados de maneira diferente no JS, para que não sejam exatamente iguais, da mesma forma que 9! == '9'.
fonte
No ES5, ele define como
isNaN (number)
retorna true se o argumento for coercitivo para NaN e, caso contrário, retornará false.E consulte a tabela de conversão ToNumber da operação abstrata . Por isso motor internamente js avaliar
ToNumber(Null)
é+0
, então, eventualmente,isNaN(null)
éfalse
fonte
Nota:
O operador == faz conversão de tipo, enquanto === não.
Site de Douglas Crockford , um site do Yahoo! Evangelista JavaScript, é um ótimo recurso para coisas assim.
fonte