Compruebe si la variable es número o cadena en JavaScript

Respuestas:

442

Si se trata de notación literal y no de constructores, puede usar typeof :.

typeof "Hello World"; // string
typeof 123;           // number

Si está creando números y cadenas a través de un constructor, como var foo = new String("foo") , debe tener en cuenta que typeofpuede volver objectpara foo.

Quizás un método más infalible para verificar el tipo sería utilizar el método encontrado en underscore.js (se puede encontrar la fuente anotada aquí ),

var toString = Object.prototype.toString;

_.isString = function (obj) {
  return toString.call(obj) == '[object String]';
}

Esto devuelve un valor booleano truepara lo siguiente:

_.isString("Jonathan"); // true
_.isString(new String("Jonathan")); // true
Sampson
fuente
69
que dice "cadena" y "número" respectivamente
Thilo
27
¡Esto no es correcto! Hay dos representaciones posibles de una cadena. alert (typeof new String ()) generará "Objeto". Peor aún, JavaScript ocasionalmente se convertirá de un lado a otro entre las dos representaciones detrás de escena para fines de optimización
George Mauer
3
@ George Según el OP, solo se evaluarán las variables existentes.
Sampson
3
Claro, pero digamos que tengo la función isString (str) {return typeof str === 'string'} algunos Java-convert pueden estar usando mi método así que var myString = new String("stuff I like"); isString(myString)esto devuelve falso. Además, no estoy exactamente seguro de cuánto tiempo dura la conversión de backgroiund, sé que cuando llamo "hola" .length, "hola" se convierte en un objeto, no estoy seguro de qué tan pronto se vuelve a convertir o si alguna vez se vincula a la variable
George Mauer
8
Es cierto, pero ¿con qué quieres usar el objeto String?
Félix Saparelli
211

La mejor manera de hacerlo es usar el isNaNtipo + casting:

Método todo actualizado:

function isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }

Lo mismo usando regex:

function isNumber(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n); } 

------------------------

isNumber('123'); // true  
isNumber('123abc'); // false  
isNumber(5); // true  
isNumber('q345'); // false
isNumber(null); // false
isNumber(undefined); // false
isNumber(false); // false
isNumber('   '); // false
BitOfUniverse
fuente
21
Esto parece una buena solución si desea contar cadenas que se analizan como números válidos.
Trevor Burnham
2
FYI: nulles forzado a 0 y vuelve verdadero paraisNumber(null);
Edward
1
qué le pasafunction is_number(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n);}
OneOfOne
1
Esto también falla para una cadena como '123abc'.
ceniza
1
@ash Gracias, también he actualizado la solución para cubrir este caso.
BitOfUniverse
73

La mejor manera que he encontrado es buscar un método en la cadena, es decir:

if (x.substring) {
// do string thing
} else{
// do other thing
}

o si desea hacer algo con la verificación de número para una propiedad de número,

if (x.toFixed) {
// do number thing
} else {
// do other thing
}

Esto es algo así como "escribir pato", depende de usted qué sentido tiene más sentido. No tengo suficiente karma para comentar, pero typeof falla para cadenas y números en caja, es decir:

alert(typeof new String('Hello World'));
alert(typeof new Number(5));

alertará "objeto".

Alokito
fuente
2
Creo que esto es mejor que typeofya que siempre puede probar una cadena, ya sea primitiva u objeto de cadena. Solo tiene que probar un método que sea único para el tipo que desee.
ADTC
Desde la perspectiva de alguien que tiene que mantener el código, elegir este camino podría ser confuso. "¿Por qué usaron la subcadena y no pasaron ningún valor? ¿Qué lógica comercial me estoy perdiendo aquí?" Como mínimo, esto debe combinarse con un comentario que explique la lógica involucrada.
Lemmings19
3
@ Lemmings19 En realidad no llama al método de subcadena, solo comprueba si x tiene un método de subcadena.
Alokito
1
Me gusta la idea de este tipo de escritura de patos, pero esto fallará por cosas como {substring:"hello"}. Sé que, para mis propósitos, acabo de probar lo que la operación específica que necesitaba hacer (módulo) hace para el tipo que necesitaba verificar (en las cadenas, el módulo devuelve indefinido) y luego verifiqué eso en lugar de obtener su tipo.
Tadhg McDonald-Jensen
30

Estas buscando isNaN():

console.log(!isNaN(123));
console.log(!isNaN(-1.23));
console.log(!isNaN(5-2));
console.log(!isNaN(0));
console.log(!isNaN("0"));
console.log(!isNaN("2"));
console.log(!isNaN("Hello"));
console.log(!isNaN("2005/12/12"));

Vea la función JavaScript isNaN () en MDN.

Jakob Gade
fuente
3
Me resulta extraño que elijan la operación inversa para el nombre del método. Parece más intuitivo llamar a isNumber ().
Nathan Taylor el
12
En realidad no es una operación inversa de 'isNumber'. NaN es un valor especial de número en javascript. isNaN convierte todo lo que se le proporciona en número y comprueba si el resultado es NaN o no. Para cadenas como "25", obtiene un resultado incorrecto.
Chetan Sastry el
1
Acabo de probar con "25" y resultó falso, como era de esperar.
Jakob Gade
2
NaN es un valor especial en el estándar IEEE 754 para aritmética de punto flotante binario, no solo una cosa de JavaScript. (Bueno, para ser precisos: "el 9007199254740990 (es decir, (2 ^ 53) -2) valores distintos de" No un número "del Estándar IEEE están representados en ECMAScript como un único valor especial de NaN" )
NickFitz
2
Tenga en cuenta que isNaNdevuelve falsepara null(pero truepara undefined).
Toni
28

Compruebe si el valor es un literal de cadena o un objeto de cadena:

function isString(o) {
    return typeof o == "string" || (typeof o == "object" && o.constructor === String);
}

Prueba de unidad:

function assertTrue(value, message) {
    if (!value) {
        alert("Assertion error: " + message);
    }
}

function assertFalse(value, message)
{
    assertTrue(!value, message);
}

assertTrue(isString("string literal"), "number literal");
assertTrue(isString(new String("String object")), "String object");
assertFalse(isString(1), "number literal");
assertFalse(isString(true), "boolean literal");
assertFalse(isString({}), "object");

Verificar un número es similar:

function isNumber(o) {
    return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
}
snorbi
fuente
1
(o.constructor === String) por sí solo parece ser suficiente, incluso para literales de cadena.
Chris Noe
2
Esto causará una excepción si o === nulo
TJ.
3
Me encantó esta solución. Sin embargo, para evitar la excepción para el caso nulo, use o ["constructor"] en lugar de o.constructor
dreamerkumar el
2
@VishalKumar Entonces, ¿esto es todo lo que uno necesita function is (type, value) { return value["constructor"] === type; }?
abandonando el
22

Desde ES2015, la forma correcta de verificar si una variable contiene un número válido es Number.isFinite(value)

Ejemplos:

Number.isFinite(Infinity)   // false
Number.isFinite(NaN)        // false
Number.isFinite(-Infinity)  // false

Number.isFinite(0)          // true
Number.isFinite(2e64)       // true

Number.isFinite('0')        // false
Number.isFinite(null)       // false
adius
fuente
1
Esto no tiene soporte en Internet Explorer. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
davedeecoder
1
No funciona en String, que es la pregunta original.
Eric Grange
18

Prueba esto,

<script>
var regInteger = /^-?\d+$/;

function isInteger( str ) {    
    return regInteger.test( str );
}

if(isInteger("1a11")) {
   console.log( 'Integer' );
} else {
   console.log( 'Non Integer' );
}
</script>
Adatapost
fuente
prueba '-2'. devuelve falso
KChen
1
¿Por qué guarda (o no edita) una respuesta que no funciona? ... Tenga en cuenta que también un número negativo puede ser un número entero.
Ason
13

La mejor manera de hacer esto:

function isNumber(num) {
  return (typeof num == 'string' || typeof num == 'number') && !isNaN(num - 0) && num !== '';
};

Esto satisface los siguientes casos de prueba:

assertEquals("ISNUMBER-True: 0", true, isNumber(0));
assertEquals("ISNUMBER-True: 1", true, isNumber(-1));
assertEquals("ISNUMBER-True: 2", true, isNumber(-500));
assertEquals("ISNUMBER-True: 3", true, isNumber(15000));
assertEquals("ISNUMBER-True: 4", true, isNumber(0.35));
assertEquals("ISNUMBER-True: 5", true, isNumber(-10.35));
assertEquals("ISNUMBER-True: 6", true, isNumber(2.534e25));
assertEquals("ISNUMBER-True: 7", true, isNumber('2.534e25'));
assertEquals("ISNUMBER-True: 8", true, isNumber('52334'));
assertEquals("ISNUMBER-True: 9", true, isNumber('-234'));

assertEquals("ISNUMBER-False: 0", false, isNumber(NaN));
assertEquals("ISNUMBER-False: 1", false, isNumber({}));
assertEquals("ISNUMBER-False: 2", false, isNumber([]));
assertEquals("ISNUMBER-False: 3", false, isNumber(''));
assertEquals("ISNUMBER-False: 4", false, isNumber('one'));
assertEquals("ISNUMBER-False: 5", false, isNumber(true));
assertEquals("ISNUMBER-False: 6", false, isNumber(false));
assertEquals("ISNUMBER-False: 7", false, isNumber());
assertEquals("ISNUMBER-False: 8", false, isNumber(undefined));
assertEquals("ISNUMBER-False: 9", false, isNumber(null));
Sitch
fuente
13
//testing data types accurately in JavaScript (opposed to "typeof")
//from http://bonsaiden.github.com/JavaScript-Garden/
function is(type, obj) {
    var clas = Object.prototype.toString.call(obj).slice(8, -1);
    return obj !== undefined && obj !== null && clas === type;
}

//basic usage
is('String', 'test'); // true
is('Array', true); // false

O adáptelo para devolver un tipo desconocido:

function realTypeOf(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1);
}

//usage
realTypeOf(999); // 'Number'

Actualización del 12 de mayo de 2012: ejemplo completo en Javascript: un tipo mejor .

mrrena
fuente
Todavía hay margen de mejora con respecto a realTypeOf: realTypeOf(NaN) -> "Number"cuál es el mismo comportamiento typeofacordado pero aún lejos de ser ideal.
Max
9

Aquí hay un enfoque basado en la idea de coaccionar la entrada a un número o cadena agregando cero o la cadena nula, y luego hacer una comparación de igualdad escrita.

function is_number(x) { return x === x+0;  }
function is_string(x) { return x === x+""; }

Por alguna razón insondable, x===x+0parece funcionar mejor quex===+x .

¿Hay algún caso donde esto falla?

En la misma vena:

function is_boolean(x) { return x === !!x; }

Esto parece ser ligeramente más rápido que cualquiera x===true || x===falseo typeof x==="boolean"(y mucho más rápido quex===Boolean(x) ).

Entonces también hay

function is_regexp(x)  { return x === RegExp(x); }

Todo esto depende de la existencia de una operación de "identidad" particular para cada tipo que puede aplicarse a cualquier valor y producir de manera confiable un valor del tipo en cuestión. No puedo pensar en tal operación para fechas.

Para NaN, hay

function is_nan(x) { return x !== x;}

Esta es básicamente la versión de subrayado, y tal como está es aproximadamente cuatro veces más rápido que isNaN(), pero los comentarios en la fuente de subrayado mencionan que "NaN es el único número que no es igual a sí mismo" y agrega un cheque para _.isNumber. ¿Por qué? ¿Qué otros objetos no serían iguales? Además, el subrayado utiliza, x !== +xpero ¿qué diferencia podría tener el+ hacer aquí?

Entonces para los paranoicos:

function is_undefined(x) { return x===[][0]; }

o esto

function is_undefined(x) { return x===void(0); }
c-smile
fuente
1
x! == + x primero intenta convertir x en un número.
Adrian Bartholomew
8

¿Puedes dividirlo por 1?

Supongo que el problema sería una entrada de cadena como: "123ABG"

var Check = "123ABG"

if(Check == Check / 1)
{
alert("This IS a number \n")
}

else
{
alert("This is NOT a number \n")
}

Justo como lo hice recientemente.

Luke
fuente
No creo que él quiera que devuelva verdadero si se trata de una serie de números. Tal vez use ===
Curtis
7

eh, ¿qué tal solo:

function IsString(obj) {
    return obj !== undefined && obj != null && obj.toLowerCase !== undefined;
}

Después de una revisión adicional muchos meses después, esto solo garantiza que objes un objeto que tiene el método o nombre de propiedad toLowerCasedefinido. Estoy avergonzado de mi respuesta. Por favor vea typeofuno de los más votados .

ZagNut
fuente
7

O simplemente use la inversión de isNaN():

if(!isNaN(data))
  do something with the number
else
  it is a string

Y sí, usar jQuery's $.isNumeric()es más divertido.

Osomanden
fuente
isNaN('123')da falso, aunque el argumento es una cadena numérica y no un tipo numérico
JustAMartin
6

Creo que la conversión de var a una cadena disminuye el rendimiento, al menos esta prueba realizada en los últimos navegadores así lo demuestra.

Así que si te importa el rendimiento, lo usaría

typeof str === "string" || str instanceof String

para verificar si la variable es una cadena (incluso si la usa var str = new String("foo"), str instanceof Stringdevolvería verdadero).

En cuanto a verificar si es un número, iría por el nativo isNaN:; función.

Roland
fuente
5

jQuery usa esto:

function isNumber(obj) {
  return !isNaN( parseFloat( obj ) ) && isFinite( obj );
}
Bounasser Abdelwahab
fuente
4

¡Esta solución resuelve muchos de los problemas planteados aquí!

Este es, con mucho, el método más confiable que he usado hasta ahora. No inventé esto, y no puedo recordar dónde lo encontré originalmente. Pero funciona donde otras técnicas fallan:

// Begin public utility /getVarType/
// Returns 'Function', 'Object', 'Array',
// 'String', 'Number', 'Boolean', or 'Undefined'
getVarType = function ( data ){
  if (undefined === data ){ return 'Undefined'; }
  if (data === null ){ return 'Null'; }
  return {}.toString.call(data).slice(8, -1);
};  
// End public utility /getVarType/

Ejemplo de corrección

var str = new String();
console.warn( getVarType(str) ); // Reports "String"    
console.warn( typeof str );      // Reports "object"

var num = new Number();
console.warn( getVarType(num) ); // Reports "Number"
console.warn( typeof num );      // Reports "object"

var list = [];
console.warn( getVarType( list ) ); // Reports "Array"
console.warn( typeof list );        // Reports "object"
Michael Mikowski
fuente
2
Y es realmente lento.
Tarazaburo, no sé de dónde sacas tus datos, pero es necesario un pequeño punto de referencia:
Michael Mikowski
No encuentro esto "realmente lento". Al probar la velocidad en más de 1 millón de iteraciones, no me parece peor que la mitad de la velocidad del typeofmétodo nativo (0.788s frente a 1.481s) en Chrome. Esto ciertamente es un rendimiento aceptable considerando los mejores resultados. ¿Por qué crees que es "realmente lento"? Tal vez es - en IE6 / 7/8? Pero todo es "realmente lento" en esos navegadores.
Michael Mikowski
Bueno, lo dije porque ya había hecho el benchmarking. Arme uno nuevo en jsperf.com/check-typeof-number-again , y typeofes 100 veces más rápido, ¿qué me estoy perdiendo?
Te estás perdiendo el hecho de que 3m ops / s no es un problema para la mayoría de los códigos al verificar el tipo. No lo llamaría "realmente lento" en ninguna medida. Mi punto de referencia se veía así: var i, k, start = + new Date (); para (i = 0; i <1000000; i ++) {k = typeof ('foo'); k = typeof (123.5); }; end = + nueva fecha (); console.log (fin - inicio);
Michael Mikowski el
4

typeof me funciona muy bien en la mayoría de los casos. Puedes intentar usar una declaración if

if(typeof x === 'string' || typeof x === 'number') {
    console.log("Your statement");
}

donde x es cualquier nombre de variable de su elección

Tanah
fuente
¿Qué agrega esta respuesta sobre la más votada?
Bartek Banachewicz
2
¿Simplicidad y claridad?
Tim Erickson
3

La mejor manera que encontré que también piensa en números positivos y negativos es de: O'Reilly Javascript y DHTML Cookbook :

function isNumber(elem) {
var str = elem.value;
var oneDecimal = false;
var oneChar = 0;
// make sure value hasn't cast to a number data type
str = str.toString( );
for (var i = 0; i < str.length; i++) {
    oneChar = str.charAt(i).charCodeAt(0);
    // OK for minus sign as first character
    if (oneChar =  = 45) {
        if (i =  = 0) {
            continue;
        } else {
            alert("Only the first character may be a minus sign.");
            return false;
        }
    }
    // OK for one decimal point
    if (oneChar =  = 46) {
        if (!oneDecimal) {
            oneDecimal = true;
            continue;
        } else {
            alert("Only one decimal is allowed in a number.");
            return false;
        }
    }
    // characters outside of 0 through 9 not OK
    if (oneChar < 48 || oneChar > 57) {
        alert("Enter only numbers into the field.");
        return false;
    }
}
return true;

}

Alex Peta
fuente
3

Errr? ¡Solo usa expresiones regulares! :)

function isInteger(val) {
  return val.match(/^[0-9]$/)
}

function isFloat(val) {
  return val.match(/^[0-9]*/\.[0-9]+$/)
}
hackerdiehack
fuente
3

dado que una cadena como '1234' con typeof mostrará 'cadena', y lo inverso nunca puede suceder (typeof 123 siempre será número), lo mejor es usar una expresión regular simple /^\-?\d+$/.test(var). O un más avanzado para unir flotantes, enteros y números negativos. /^[\-\+]?[\d]+\.?(\d+)?$/ El lado importante de esto .testes que NO arrojará una excepción si el var no es una cadena, el valor puede ser cualquier cosa.

var val, regex = /^[\-\+]?[\d]+\.?(\d+)?$/;

regex.test(val)       // false 
val = '1234';
regex.test(val)       // true
val = '-213';
regex.test(val)       // true
val = '-213.2312';
regex.test(val)       // true
val = '+213.2312';
regex.test(val)       // true
val = 123;
regex.test(val)       // true
val = new Number(123);
regex.test(val)       // true
val = new String('123');
regex.test(val)       // true
val = '1234e';
regex.test(val)       // false 
val = {};
regex.test(val)       // false 
val = false;
regex.test(val)       // false 
regex.test(undefined) // false 
regex.test(null)      // false 
regex.test(window)    // false 
regex.test(document)  // false 

Si está buscando el tipo real, entonces typeof solo servirá.

pocesar
fuente
3

La respuesta de @ BitOfUniverse es buena, y se me ocurre una nueva forma:

function isNum(n) {
    return !isNaN(n/0);
}

isNum('')  // false
isNum(2)   // true
isNum('2k') // false
isNum('2')  //true

0que no puede ser dividendo, pero aquí la función funciona perfectamente.

remolcar
fuente
2

Comprobación de tipo

Puede verificar el tipo de variable utilizando el typeofoperador:

typeof variable

Comprobación de valor

El siguiente código devuelve verdadero para los números y falso para cualquier otra cosa:

!isNaN(+variable);
Amir Fo
fuente
variable var = '123'; console.log (! isNaN (+ variable)); da verdadero aunque es una cadena y no un tipo de número
JustAMartin
¡Porque '123' es un número! Si desea saber el tipo de variable, ¡puede usar fácilmente el typeofoperador! @JustAMartin
Amir Fo
Sí, pero la pregunta original era distinguir cualquier variable de tipo cadena de las variables de tipo numérico. '123' sigue siendo una cadena. Si paso 123, la respuesta debería ser numberpero si paso '123' o 'abc' o cualquier otro literal citado, es una cadena, y no importa si se puede analizar en un número o no.
JustAMartin
@JustAMartin Ok, edité mi respuesta.
Amir Fo
1

La operación XOR se puede utilizar para detectar números o cadenas. número ^ 0 siempre dará el número como salida y la cadena ^ 0 dará 0 como salida.

Example: 
   1)  2 ^ 0 = 2
   2)  '2' ^ 0  = 2
   3)  'Str' ^ 0 = 0
Himanshu Shekhar
fuente
1

Simple y minucioso:

function isNumber(x) {
  return parseFloat(x) == x
};

Casos de prueba:

console.log('***TRUE CASES***');
console.log(isNumber(0));
console.log(isNumber(-1));
console.log(isNumber(-500));
console.log(isNumber(15000));
console.log(isNumber(0.35));
console.log(isNumber(-10.35));
console.log(isNumber(2.534e25));
console.log(isNumber('2.534e25'));
console.log(isNumber('52334'));
console.log(isNumber('-234'));
console.log(isNumber(Infinity));
console.log(isNumber(-Infinity));
console.log(isNumber('Infinity'));
console.log(isNumber('-Infinity'));

console.log('***FALSE CASES***');
console.log(isNumber(NaN));
console.log(isNumber({}));
console.log(isNumber([]));
console.log(isNumber(''));
console.log(isNumber('one'));
console.log(isNumber(true));
console.log(isNumber(false));
console.log(isNumber());
console.log(isNumber(undefined));
console.log(isNumber(null));
console.log(isNumber('-234aa'));
Queso Marred
fuente
0

Simplemente use

myVar.constructor == String

o

myVar.constructor == Number

si desea manejar cadenas definidas como objetos o literales y guardados, no desea utilizar una función auxiliar.

Jonathon
fuente
0
function IsNumeric(num) {
    return ((num >=0 || num < 0)&& (parseInt(num)==num) );
}
manguera
fuente
0

Muy tarde a la fiesta; sin embargo, lo siguiente siempre me ha funcionado bien cuando quiero verificar si alguna entrada es una cadena o un número de una sola vez.

return !!Object.prototype.toString.call(input).match(/\[object (String|Number)\]/);
Wil Moore III
fuente
0

Creó un jsperf en la comprobación de si una variable es un número. ¡Bastante interesante! typeof en realidad tiene un uso de rendimiento. Utilizando typeofpara cualquier otra cosa que no sean números, generalmente va un tercio de la velocidad como unvariable.constructor ya que la mayoría de los tipos de datos en JavaScript son Objetos; los números no son!

http://jsperf.com/jemiloii-fastest-method-to-check-if-type-is-a-number

typeof variable === 'number'El | más rápido | si desea un número, como 5, y no '5'
typeof parseFloat(variable) === 'number' | más rápido | si desea un número, como 5 y '5'

isNaN()es más lento, pero no mucho más lento. Tenía grandes esperanzas parseInty parseFloat, sin embargo, eran terriblemente más lentas.

jemiloii
fuente
0

Para detectar números, el siguiente pasaje de JavaScript: The Good Parts de Douglas Crockford es relevante:

La función isFinite es la mejor manera de determinar si un valor se puede usar como un número porque rechaza NaN e Infinity. Desafortunadamente, isFinite intentará convertir su operando a un número, por lo que no es una buena prueba si un valor no es realmente un número. Es posible que desee definir su propia función isNumber:

var isNumber = function isNumber(value) { return typeof value === 'number' &&
            isFinite(value);
};
Stephen Niedzielski
fuente