¿Por qué isNaN(" ") es igual a false
Tengo una pregunta rápida (¡Espero!). En JS, ¿por qué isNaN(" ")
evalúa a false, pero isNaN(" x")
evalúa a true?
Estoy realizando operaciones numéricas en un campo de entrada de texto, y estoy comprobando si el campo es null, "", o NaN. Cuando alguien escribe un puñado de espacios en el campo, mi validación falla en los tres, y estoy confundido en cuanto a por qué pasa la verificación de isNaN.
Gracias!
22 answers
JavaScript interpreta una cadena vacía como un 0, que luego falla la prueba isNaN. Puede usar parseInt en la cadena primero, lo que no convertirá la cadena vacía a 0. El resultado debe entonces fallar isNaN.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-05 15:27:11
Usted puede encontrar esto sorprendente o tal vez no, pero aquí hay un código de prueba para mostrar la locura del motor JavaScript.
document.write(isNaN("")) // false
document.write(isNaN(" ")) // false
document.write(isNaN(0)) // false
document.write(isNaN(null)) // false
document.write(isNaN(false)) // false
document.write("" == false) // true
document.write("" == 0) // true
document.write(" " == 0) // true
document.write(" " == false) // true
document.write(0 == false) // true
document.write(" " == "") // false
Así que esto significa que
" " == 0 == false
Y
"" == 0 == false
Pero
"" != " "
Diviértete:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-04 18:16:00
Para entenderlo mejor, abra Ecma-Script spec pdf en la página 43 "ToNumber Applied to the String Type"
Si una cadena tiene una sintaxis numérica, que puede contener cualquier número de caracteres de espacio en blanco, se puede convertir a tipo de número. La cadena vacía se evalúa como 0. También la cadena 'Infinity' debería dar
isNaN('Infinity'); // false
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-05 15:32:00
Intenta usar:
alert(isNaN(parseInt(" ")));
O
alert(isNaN(parseFloat(" ")));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-05 15:27:27
De MDN
razón del problema al que se enfrenta
Cuando el argumento de la función isNaN no es de tipo Number, el valor se coacciona primero a un Número. El valor resultante se prueba para determinar si es NaN.
Es posible que desee comprobar la siguiente respuesta completa que cubre la comparación NaN para la igualdad también.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:02
Creo que es debido a la escritura de Javascript: ' '
se convierte a cero, mientras que 'x'
no lo es:
alert(' ' * 1); // 0
alert('x' * 1); // NaN
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-05 15:27:37
Si desea implementar una función isNumber precisa, aquí hay una forma de hacerlo desde Javascript: Las Partes buenas por Douglas Crockford [página 105]
var isNumber = function isNumber(value) {
return typeof value === 'number' &&
isFinite(value);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-05 15:38:23
La Respuesta No del Todo Correcta
La respuesta de Antonio Haley altamente votada y aceptada aquí hace una suposición errónea de que este proceso pasa por la función parseInt
de JavaScript:
Puede usar parseInt en la cadena ... El resultado debe entonces fallar isNaN.
Podemos refutar fácilmente esta afirmación con la cadena "123abc"
:
parseInt("123abc") // 123 (a number...
isNaN("123abc") // true ...which is not a number)
Con esto, podemos ver que la función parseInt
de JavaScript devuelve "123abc"
como el número 123
, aún su función isNaN
nos dice que "123abc"
no es un número.
La Respuesta Correcta
ECMAScript-262 define cómo funciona la comprobación isNaN
en sección 18.2.3.
18.2.3
isNaN
(Número)La función
isNaN
es el objeto intrínseco%isNaN%
. Cuando se llama a la funciónisNaN
con un número de argumento, se siguen los siguientes pasos:
- Sea
num
?ToNumber(number)
.- Si
num
esNaN
, regresartrue
.- De lo contrario, devuelve
false
.
La función ToNumber
a la que hace referencia también está definida en La sección 7.1.3 de ECMAScript-262. Aquí, nos dicen cómo JavaScript maneja las cadenas que se pasan a esta función.
El primer ejemplo dado en la pregunta es una cadena que no contiene más que caracteres de espacio en blanco. Esta sección establece que:
Un
StringNumericLiteral
que está vacío o contiene solo espacio en blanco se convierte en+0
.
La cadena de ejemplo " "
se convierte entonces a +0
, que es un número.
La misma sección también dice:
Si la gramática no puede interpretar el
String
como una expansión deStringNumericLiteral
, entonces el resultado deToNumber
esNaN
.
Sin citar todas las comprobaciones contenidas en esa sección, el ejemplo " x"
dado en la pregunta cae en la condición anterior, ya que no puede interpretarse como un StringNumericLiteral
. " x"
es por lo tanto convertido a NaN
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:48
No estoy seguro de por qué, pero para evitar el problema, siempre puede recortar los espacios en blanco antes de verificar. Probablemente quieras hacer eso de todos modos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-05 15:28:00
La función isNaN("")
realiza una cadena para Numerar tipo coerción
ECMAScript 3-5 define los siguientes valores de retorno para el operador typeof:
- indefinido
- object (null, objects, arrays)
- booleano
- número
- string
- función
Mejor envolver nuestra prueba en un cuerpo de función:
function isNumber (s) {
return typeof s == 'number'? true
: typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
: (typeof s).match(/object|function/)? false
: !isNaN(s)
}
Esta función no está destinada a probar la variable type , sino que prueba el valor coaccionado. Por ejemplo, los booleanos y las cadenas se coaccionan a números, por lo que tal vez desee llamar a esta función como isNumberCoerced()
Si no hay necesidad de probar tipos que no sean string y number , entonces el siguiente fragmento de código podría usarse como parte de alguna condición:
if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
alert("s is a number")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-13 21:38:09
Le sugiero que use la siguiente función si realmente desea una comprobación adecuada si es un entero:
function isInteger(s)
{
return Math.ceil(s) == Math.floor(s);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-26 09:39:40
Que isNaN(" ")
es false es parte del comportamiento confuso de la función global isNaN
debido a su coerción de no-números a un tipo numérico.
De MDN:
Desde las primeras versiones de la especificación de la función
isNaN
, su comportamiento para argumentos no numéricos ha sido confuso. Cuando el argumento de la funciónisNaN
no es de tipo Number, el valor se coacciona primero a un Número. El valor resultante se prueba para determinar si esNaN
. Por lo tanto, para los no-números que cuando se coaccionan a tipo numérico dan como resultado un valor numérico no-NaN válido (notablemente la cadena vacía y las primitivas booleanas, que cuando se coaccionan dan valores numéricos cero o uno), el valor devuelto "falso" puede ser inesperado; la cadena vacía, por ejemplo, seguramente "no es un número."
Tenga en cuenta también que con ECMAScript 6, también existe ahora el método Number.isNaN
, que según MDN:
En comparación con el global
isNaN()
function,Number.isNaN()
no sufre el problema de convertir forzosamente el parámetro a un número. Esto significa que ahora es seguro pasar valores que normalmente se convertirían aNaN
, pero que en realidad no son el mismo valor queNaN
. Esto también significa que solo los valores del tipo number, que también sonNaN
, devuelventrue
.
Desafortunadamente :
Incluso el método ECMAScript 6 Number.isNaN
tiene sus propios problemas, como se describe en la publicación del blog - Arreglando el feo JavaScript y ES6 NaN problema.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 15:22:11
Como otros explicaron, la función isNaN
coaccionará la cadena vacía en un número antes de validarla, cambiando así una cadena vacía en 0 (que es un número válido).
Sin embargo, encontré que la función parseInt
devolverá NaN
cuando intente analizar una cadena vacía o una cadena con solo espacios. Como tal, la siguiente combinación parece estar funcionando bien:
if ( isNaN(string) || isNaN(parseInt(string)) ) console.log('Not a number!');
Esta comprobación funcionará para números positivos, números negativos y números con un punto decimal, así que lo creo cubre todos los casos numéricos comunes.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-28 03:15:11
Esta función parecía funcionar en mis pruebas
function isNumber(s) {
if (s === "" || s === null) {
return false;
} else {
var number = parseInt(s);
if (number == 'NaN') {
return false;
} else {
return true;
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-03 12:41:26
¿Qué pasa con
function isNumberRegex(value) {
var pattern = /^[-+]?\d*\.?\d*$/i;
var match = value.match(pattern);
return value.length > 0 && match != null;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-12 13:22:57
La función isNaN
espera un Número como argumento, por lo que los argumentos de cualquier otro tipo (en su caso una cadena) se convertirán en Número antes de que se realice la lógica de la función real. (Tenga en cuenta que NaN
es también un valor de tipo Número!)
Por cierto. esto es común para todas las funciones integradas-si esperan un argumento de cierto tipo, el argumento real se convertirá usando las funciones de conversión estándar. Hay conversiones estándar entre todos los tipos básicos (bool, string, number, object, date, null, undefined.)
La conversión estándar de String
a Number
se puede invocar explícitamente con Number()
. Así que podemos ver que:
-
Number(" ")
evalúa a0
-
Number(" x")
evalúa aNaN
Dado esto, el resultado de la función isNaN
es completamente lógico!
La verdadera pregunta es por qué la conversión estándar de Cadena a Número funciona como lo hace. La conversión de cadena a número es realmente destinado a convertir cadenas numéricas como "123 "o" 17.5e4 " a los números equivalentes. La conversión primero omite los espacios en blanco iniciales (por lo que "123" es válido) y luego intenta analizar los silencios como un número. Si no se puede analizar como un número ("x" no lo es), entonces el resultado es NaN. Pero existe la regla especial explícita de que una cadena vacía o solo espacios en blanco se convierte a 0. Así que esto explica la conversión.
Referencia: http://www.ecma-international.org/ecma-262/5.1/#sec-9.3.1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-23 09:25:40
Escribí esta pequeña función rápida para ayudar a resolver este problema.
function isNumber(val) {
return (val != undefined && val != null && val.toString().length > 0 && val.toString().match(/[^0-9\.\-]/g) == null);
};
Simplemente comprueba si hay caracteres que no sean numéricos (0-9), que no sean '-' o '.', y que no son indefinidos, null o vacío y devuelve true si no hay coincidencias. :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-14 00:27:12
El JavaScript la función incorporada isNaN , es - como debería esperarse por defecto - un "Operador de Tipo Dinámico".
Por lo tanto, todos los valores que (durante el proceso DTC) pueden producir un verdadero | falso simple como "", " ", " 000"
, no pueden ser NaN.
Lo que significa que el argumento suministrado primero experimentará una conversión como en:
function isNaNDemo(arg){
var x = new Number(arg).valueOf();
return x != x;
}
Explicación:
En la línea superior del cuerpo de la función, estamos (primero) tratando de convierta correctamente el argumento en un objeto number. Y (segundo), usando el operador de punto estamos - para nuestra propia conveniencia - despojando inmediatamente, el primitivo valor del objeto creado.
En la segunda línea, estamos tomando el valor obtenido en el paso anterior, y la ventaja del hecho de que NaN no es igual a nada en el universo, ni siquiera a sí mismo, por ejemplo: NaN == NaN >> false
para finalmente compararlo (para la desigualdad) con sí mismo.
De esta manera la función return producirá verdadero solo cuando, y solo si, el argumento proporcionado-return, es un intento fallido de conversión a un objeto number, es decir, un número not-a-number; por ejemplo, NaN.
isNaNstatic( )
Sin embargo, para un Operador de Tipo estático - si es necesario y cuando sea necesario - podemos escribir una función mucho más simple como:
function isNaNstatic(x){
return x != x;
}
Y evitar el DTC por completo para que si el argumento no es explícitamente un número NaN, devolverá false. Por lo tanto, la prueba contra lo siguiente:
isNaNStatic(" x"); // will return false
porque sigue siendo una cuerda.
Sin embargo:
isNaNStatic(1/"x"); // will of course return true.
como por ejemplo isNaNStatic(NaN); >> true
.
Pero contrariamente a isNaN
, el isNaNStatic("NaN"); >> false
porque (el argumento) es una cadena ordinaria.
P. S.: La versión estática de isNaN puede ser muy útil en escenarios de codificación modernos. Y puede muy bien ser una de las principales razones por las que me tomé mi tiempo para publicar esto.
Saludos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-08 01:01:53
isNAN(<argument>)
es una función para decir si el argumento dado es un número ilegal.
isNaN
tipifica los argumentos en Tipo de número. Si desea comprobar si el argumento es Numérico o no? Utilice la función $.isNumeric()
en jQuery.
Es decir, isNaN(foo) es equivalente a isNaN(Número(foo)) Acepta cualquier cadena que tenga todos los números como números por razones obvias. Para ex.
isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-12 06:32:11
Yo uso esto
function isNotANumeric(val) {
if(val.trim && val.trim() == "") {
return true;
} else {
return isNaN(parseFloat(val * 1));
}
}
alert(isNotANumeric("100")); // false
alert(isNotANumeric("1a")); // true
alert(isNotANumeric("")); // true
alert(isNotANumeric(" ")); // true
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-27 12:41:53
NaN
!== "no es un número"
NaN
es un valor de Tipo Numérico
Esta es una definición de isNaN () en ECMAScript
1. Let num be ToNumber(number).
2. ReturnIfAbrupt(num).
3. If num is NaN, return true.
4. Otherwise, return false.
Intente convertir cualquier valor en Número.
Number(" ") // 0
Number("x") // NaN
Number(null) // 0
Si desea determinar si el valor es NaN
, primero debe intentar convertirlo en un valor numérico.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-08 10:03:56
Al verificar si cierto valor de cadena con espacios en blanco o " "
es isNaN
tal vez intente realizar la validación de cadena, ejemplo:
// value = "123 "
if (value.match(/\s/) || isNaN(value)) {
// do something
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-13 07:07:56