¿Cómo verificar si una variable es un número entero en JavaScript?

405

¿Cómo verifico si una variable es un número entero en JavaScript y lanzo una alerta si no lo es? Intenté esto, pero no funciona:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>
JBa
fuente
2
Una posibilidad aquí es usar parseInt.
Paul
2
jsben.ch/#/htLVw - un punto de referencia para las formas comunes de hacerlo
EscapeNetscape
Todas las respuestas aquí están realmente desactualizadas. Hoy, recomiendo apegarse a Number.isIntegercuál es la forma menos hacky.
Benjamin Gruenbaum
@Benjamim, ¿qué pasa si el número es una cadena que se puede convertir a un entero? y en HTML todo es una cadena ... entonces Number.isInteger ("69") es falso
joedotnot

Respuestas:

344

Utilice el operador === ( igualdad estricta ) como se muestra a continuación,

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")
pranag
fuente
95
esto cuenta NaN como un entero. También funciona peor contra mi método. jsperf.com/numbers-and-integers
Blake Regalia
2
si ejecuta su ejemplo a través del código anterior, alerta como un número entero y el otro como un número entero, que es el caso ... en el caso de NaN también el tipo de NaN es diferente del tipo del valor de retorno de pareInt () .....
pranag 01 de
1
¿Podrías elaborar un poco? el "ejemplo" solo demuestra que el uso de parseInt produce un rendimiento peor que el uso de la palabra clave typeof y el operador de módulo. pero entiendo a qué te refieres ahora (NaN! = NaN)
Blake Regalia
44
@connorbode en javascript, todos los números tienen el mismo tipo (no hay flotante ni doble), por lo que 2.0 === 2dado que el decimal innecesario es solo una representación diferente del mismo número, parseInt(2.0) === 2.0es equivalente a lo parseInt(2) === 2que es cierto
Michael Theriot
1
@BlakeRegalia: Aunque es rápido, su método no pasa todos los valores posibles de esta respuesta: stackoverflow.com/a/14794066/843732
c00000fd
506

Eso depende, ¿también quieres lanzar cadenas como enteros potenciales?

Esto lo hara:

function isInt(value) {
  return !isNaN(value) && 
         parseInt(Number(value)) == value && 
         !isNaN(parseInt(value, 10));
}

Con operaciones bit a bit

Análisis y verificación simples

function isInt(value) {
  var x = parseFloat(value);
  return !isNaN(value) && (x | 0) === x;
}

Cortocircuito y guardar una operación de análisis:

function isInt(value) {
  if (isNaN(value)) {
    return false;
  }
  var x = parseFloat(value);
  return (x | 0) === x;
}

O tal vez ambos de una sola vez:

function isInt(value) {
  return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value))
}

Pruebas:

isInt(42)        // true
isInt("42")      // true
isInt(4e2)       // true
isInt("4e2")     // true
isInt(" 1 ")     // true
isInt("")        // false
isInt("  ")      // false
isInt(42.1)      // false
isInt("1a")      // false
isInt("4e2a")    // false
isInt(null)      // false
isInt(undefined) // false
isInt(NaN)       // false

Aquí está el violín: http://jsfiddle.net/opfyrqwp/28/

Actuación

Las pruebas revelan que la solución de cortocircuito tiene el mejor rendimiento (ops / seg).

// Short-circuiting, and saving a parse operation
function isInt(value) {
  var x;
  if (isNaN(value)) {
    return false;
  }
  x = parseFloat(value);
  return (x | 0) === x;
}

Aquí hay un punto de referencia: http://jsben.ch/#/htLVw

Si te apetece una forma más corta y obtusa de cortocircuito:

function isInt(value) {
  var x;
  return isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
}

Por supuesto, sugeriría dejar que el minificador se encargue de eso.

krisk
fuente
44
@krisk - Votado para múltiples soluciones. También realizó una prueba rápida en las 4 variantes que proporcionó: jsperf.com/tfm-is-integer , y determinó que la solución de cortocircuito tiene el mejor rendimiento.
tfmontague
1
Está volviendo falso el 2099999999999999: - (
jkucharovic
1
@jkucharovic el operador OR bit a bit es el culpable. El uso de la versión no bit a bit devolverá verdadero.
krisk
1
Esto hace '2'. evalúe como verdadero
cyberwombat
1
@cyberwombat bueno, ese es un número decimal 2.0 :-)
Kuba Beránek
120

Suponiendo que no sabe nada sobre la variable en cuestión, debe adoptar este enfoque:

if(typeof data === 'number') {
    var remainder = (data % 1);
    if(remainder === 0) {
        // yes, it is an integer
    }
    else if(isNaN(remainder)) {
        // no, data is either: NaN, Infinity, or -Infinity
    }
    else {
        // no, it is a float (still a number though)
    }
}
else {
    // no way, it is not even a number
}

Para hacerlo mas simple:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}
Blake Regalia
fuente
8
¿Qué quieres decir? Esto busca tipos de datos en javascript, "1.0"es una cadena y, por lo tanto, no es un número. De 1lo contrario , será el valor de una variable si la configura de esta manera var my_var=1.0;, que esta función identifica correctamente como un entero.
Blake Regalia
44
Pronto, Number.isInteger()funcionará ... hasta entonces, esta es una buena manera de hacerlo
Claudiu
Number.isInteger no funciona para mí. Debo estar haciendo algo mal. La solución de Blake% 1 funciona perfectamente.
mcmacerson
104

Number.isInteger() Parece ser el camino a seguir.

MDN también ha proporcionado el siguiente polyfill para navegadores que no admiten Number.isInteger() , principalmente todas las versiones de IE.

Enlace a la página de MDN

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};
Walter Roman
fuente
2
MDN tiene la prueba en 9007199254740992 eliminado
Bernhard Döbler
2
Esta es la respuesta más directa y "correcta". Quiero decir, JavaScript ya tiene el método para verificar la integridad. No es necesario escribir uno nuevo. isNaN () prueba la numericidad, no la entereza.
globewalldesk
66

Puede verificar si el número tiene un resto:

var data = 22;

if(data % 1 === 0){
   // yes it's an integer.
}

Eso sí, si su entrada también puede ser texto y desea verificar primero que no, entonces puede verificar el tipo primero:

var data = 22;

if(typeof data === 'number'){
     // yes it is numeric

    if(data % 1 === 0){
       // yes it's an integer.
    }
}
No
fuente
3
@Erwinus: ejecutar 0 % 1 === 0en la consola. Vuelve truecomo 0 % 1vueltas 0.
No, el
¿Lo has
probado
1
@Erwinus: 0 % 1regresa 0en modo de compatibilidad IE9, IE8 e IE7.
No
Pruébalo en un viejo IE real. Además, siempre es una buena forma de programar para verificar cero y no confiar en el navegador qué hacer.
Codebeat
6262
@Erwinus: Creo que confundiste tus hechos. Un error de división por cero se produce cuando divide por cero, no cuando divide cero por un número. Nada que ver con la versión de IE en absoluto.
No, el
22

Puede usar una expresión regular simple:

function isInt(value) {
    var er = /^-?[0-9]+$/;
    return er.test(value);
}
Marcio Mazzucato
fuente
15

En primer lugar, NaN es un "número" (sí, sé que es extraño, simplemente rodar con él), y no una "función".

Debe verificar si el tipo de la variable es un número, y para verificar el número entero, usaría el módulo.

alert(typeof data === 'number' && data%1 == 0);
Phil
fuente
2
debe ser: alert (typeof data == 'number' && (data == 0 || data% 1 == 0)); para evitar la división por cero.
Codebeat
19
@Erwinus 0% 1 sigue siendo división por 1.
Phil
@Phil, (0 == 0 || 0 % 1 == 0)evaluará a true.
tomekwi el
Ah, por cierto 0 % 1 == 0también evalúa a true! %no es división!
tomekwi
13

Tenga cuidado al usar

num% 1

cadena vacía ('') o booleana (verdadero o falso) volverá como entero. Es posible que no quieras hacer eso

false % 1 // true
'' % 1 //true

Number.isInteger (datos)

Number.isInteger(22); //true
Number.isInteger(22.2); //false
Number.isInteger('22'); //false

función incorporada en el navegador. Dosis compatible con navegadores antiguos

Alternativas:

Math.round(num)=== num

Sin embargo, Math.round () también fallará para cadenas vacías y booleanas

Jhankar Mahbub
fuente
8

Para verificar si un entero como póster quiere:

if (+data===parseInt(data)) {return true} else {return false}

observe + delante de los datos (convierte la cadena en número) y === para obtener información exacta.

Aquí hay ejemplos:

data=10
+data===parseInt(data)
true

data="10"
+data===parseInt(data)
true

data="10.2"
+data===parseInt(data)
false
usuario603749
fuente
66
Esta parece ser la solución más inteligente para mi caso (donde no me importa si es un número entero en una cadena). Sin embargo: ¿por qué no simplemente ir return (+data===parseInt(data))?
Señor suizo
6
if(Number.isInteger(Number(data))){
    //-----
}
invitado
fuente
1
El mismo comentario que a continuación: No es compatible con IE y Safari .
entrecruzado el
@crisscross Ahora es compatible con todo excepto IE, lo cual es solo una preocupación si es compatible con sistemas operativos heredados.
faintsignal
6

La solución más simple y limpia de pre-ECMAScript-6 (que también es lo suficientemente robusta como para devolver falso incluso si se pasa un valor no numérico como una cadena o nulo a la función) sería la siguiente:

function isInteger(x) { return (x^0) === x; } 

La siguiente solución también funcionaría, aunque no tan elegante como la anterior:

function isInteger(x) { return Math.round(x) === x; }

Tenga en cuenta que Math.ceil () o Math.floor () podrían usarse igualmente bien (en lugar de Math.round ()) en la implementación anterior.

O alternativamente:

function isInteger(x) { return (typeof x === 'number') && (x % 1 === 0); }

Una solución incorrecta bastante común es la siguiente:

function isInteger(x) { return parseInt(x, 10) === x; }

Si bien este enfoque basado en parseInt funcionará bien para muchos valores de x, una vez que x se vuelva bastante grande, no funcionará correctamente. El problema es que parseInt () coacciona su primer parámetro a una cadena antes de analizar los dígitos. Por lo tanto, una vez que el número se vuelve lo suficientemente grande, su representación de cadena se presentará en forma exponencial (por ejemplo, 1e + 21). En consecuencia, parseInt () intentará analizar 1e + 21, pero dejará de analizar cuando llegue al carácter e y, por lo tanto, devolverá un valor de 1. Observe:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

> parseInt(1000000000000000000000, 10) === 1000000000000000000000
false
Arsen Aleksanyan
fuente
6

¿Por qué nadie ha mencionado Number.isInteger()?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger

Funciona perfectamente para mí y resuelve el problema con el NaNcomienzo de un número.

noches
fuente
1
Tenga en cuenta que este es ES6, por lo que los navegadores más antiguos (como IE <= 11) no lo admiten. Los documentos anteriores proporcionan un polyfill.
obispo
Alguien mencionó Number.isInteger(), 3.5 años antes que usted: stackoverflow.com/a/27424770/5208540
Alex Stragies
si vamos a capturar un valor de una entrada, verifique, Number.isInteger siempre devolverá falso ya que el valor de entrada es de tipo de datos de cadena
Shinigamae
6

En ES6 se agregan 2 nuevos métodos para Number Object.

En él, el método Number.isInteger () devuelve verdadero si el argumento es un entero.

Ejemplo de uso:

Number.isInteger(10);        // returns true
Number.isInteger(10.5);      // returns false
Arun Joshla
fuente
4

El estándar ECMA-262 6.0 (ES6) incluye Number.isInteger función .

Para agregar soporte para el navegador antiguo, recomiendo usar una solución fuerte y compatible con la comunidad de:

https://github.com/paulmillr/es6-shim

que es pura biblioteca de polyfills ES6 JS .

Tenga en cuenta que esta lib requiere es5-shim, solo siga README.md.

gavenkoa
fuente
4

Puede intentar Number.isInteger(Number(value))si valuepuede ser un número entero en forma de cadena, por ejemplo, var value = "23"y desea que esto evalúe true. Evite intentarlo Number.isInteger(parseInt(value))porque esto no siempre devolverá el valor correcto. por ejemplo, si var value = "23abc"y usa elparseInt implementación, aún sería verdadero.

Pero si desea valores estrictamente enteros, entonces probablemente Number.isInteger(value)debería hacer el truco.

gbozee
fuente
1
Tenga en cuenta que esto no es compatible con IE; como se ha dicho aquí, en el docu Tengo mi alforja se detuvo debido a esto, especialmente si el var se está comprobando es indefinido
mikewasmike
4
var x = 1.5;
if(!isNaN(x)){
 console.log('Number');
 if(x % 1 == 0){
   console.log('Integer');
 }
}else {
 console.log('not a number');
}
Hemant
fuente
3
Después de 29 respuestas, uno esperaría un poco más de explicaciones para que su respuesta destaque ...
brasofilo
3

Verifique si la variable es igual a esa misma variable redondeada a un entero, así:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}
Elliot Bonneville
fuente
Usted puede arreglar muy fácilmente la edición de esta función con la devolución truede NaN, por un simple cambio !=de !==e invirtiendo los ifbloques. Esto funciona porque NaNes el único valor en JavaScript que no es igual a sí mismo. Por ejemplo, el nuevo código debería serif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99
3

Además, Number.isInteger(). Quizás Number.isSafeInteger()es otra opción aquí usando el ES6 especificado.

Para rellenar políticamente Number.isSafeInteger(..)en navegadores anteriores a ES6:

Number.isSafeInteger = Number.isSafeInteger || function(num) {
    return typeof num === "number" && 
           isFinite(num) && 
           Math.floor(num) === num &&
           Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
};
zangw
fuente
3

Number.isInteger() es la mejor manera si su navegador lo admite, si no, creo que hay muchas maneras de hacerlo:

function isInt1(value){
  return (value^0) === value
}

o:

function isInt2(value){
  return (typeof value === 'number') && (value % 1 === 0); 
}

o:

function isInt3(value){
  return parseInt(value, 10) === value; 
}

o:

function isInt4(value){
  return Math.round(value) === value; 
}

ahora podemos probar los resultados:

var value = 1
isInt1(value)   // return true
isInt2(value)   // return true
isInt3(value)   // return true
isInt4(value)   // return true

var value = 1.1
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = 1000000000000000000
isInt1(value)   // return false
isInt2(value)   // return true
isInt3(value)   // return false
isInt4(value)   // return true

var value = undefined
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = '1' //number as string
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

Por lo tanto, todos estos métodos funcionan, pero cuando el número es muy grande, el operador parseInt y ^ no funcionaría bien.

Charles Chu
fuente
3

Solo intenta esto:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}
Jan WebDev
fuente
Number.isInteger () no es compatible con todas las versiones de los navegadores IE.
SKR
2

Podrías usar esta función:

function isInteger(value) {
    return (value == parseInt(value));
}

Volverá verdadero incluso si el valor es una cadena que contiene un valor entero.
Entonces, los resultados serán:

alert(isInteger(1)); // true
alert(isInteger(1.2)); // false
alert(isInteger("1")); // true
alert(isInteger("1.2")); // false
alert(isInteger("abc")); // false
ferhrosa
fuente
2

Mi acercamiento:

a >= 1e+21La prueba solo puede pasar por un valor que debe ser un número y uno muy grande. Esto cubrirá todos los casos con seguridad, a diferencia de otras soluciones que se han proporcionado en esta discusión.

a === (a|0)Si el argumento de la función dada es exactamente (===) el mismo que el valor transformado a nivel de bits, significa que el argumento es un número entero.

a|0devolverá 0cualquier valor aque no sea un número , y si de ahecho es un número, eliminará cualquier cosa después del punto decimal, por lo que 1.0001se convertirá1

function isInteger(a){
    return a >= 1e+21 ? true : a === (a|0)
}

/// tests ///////////////////////////
[
  1,                        // true
  1000000000000000000000,   // true
  4e2,                      // true
  Infinity,                 // true
  1.0,                      // true
  1.0000000000001,          // false
  0.1,                      // false
  "0",                      // false
  "1",                      // false
  "1.1",                    // false
  NaN,                      // false
  [],                       // false
  {},                       // false
  true,                     // false
  false,                    // false
  null,                     // false
  undefined                 // false
].forEach( a => console.log(typeof a, a, isInteger(a)) )

vsync
fuente
1
¡Buena idea! También me gusta que haya mostrado sus pruebas, pero desafortunadamente esto no considera un valor de cadena de "0".
Jammer
Hola @vsync, no intencionalmente. Originalmente voté pero decidí revertirlo debido a mi comentario anterior. Debo haber hecho doble clic accidentalmente o algo así.
Jammer
1

Puede usar regexp para esto:

function isInteger(n) {
    return (typeof n == 'number' && /^-?\d+$/.test(n+''));
}
macloving
fuente
1

Usa el |operador:

(5.3 | 0) === 5.3 // => false
(5.0 | 0) === 5.0 // => true

Entonces, una función de prueba podría verse así:

var isInteger = function (value) {
  if (typeof value !== 'number') {
    return false;
  }

  if ((value | 0) !== value) {
    return false;
  }

  return true;
};
Golo Roden
fuente
1

Esto resolverá un escenario más ( 121. ), un punto al final

function isInt(value) {
        var ind = value.indexOf(".");
        if (ind > -1) { return false; }

        if (isNaN(value)) {
            return false;
        }

        var x = parseFloat(value);
        return (x | 0) === x;

    }
Muhammed Rafiq
fuente
1

Para valores enteros positivos sin separadores:

return ( data !== '' && data === data.replace(/\D/, '') );

Pruebas 1. si no está vacío y 2. si el valor es igual al resultado de un reemplazo de un carácter sin dígitos en su valor.

DanielL
fuente
1

Ok tengo menos, porque no describió mi ejemplo, así que más ejemplos :):

Uso expresión regular y método de prueba:

var isInteger = /^[0-9]\d*$/;

isInteger.test(123); //true
isInteger.test('123'); // true
isInteger.test('sdf'); //false
isInteger.test('123sdf'); //false

// If u want to avoid string value:
typeof testVal !== 'string' && isInteger.test(testValue);
Vasyl Gutnyk
fuente
Obtuve menos probablemente porque la prueba no es una función.
imlokesh
@imlokesh, ¿qué quieres decir con "no es una función"? oO Escribí que uso el "método de prueba".
Vasyl Gutnyk
@imlokesh no hay problema, solo te pregunto porque lo usé en producción :) y pensé que encontraste algún error :)
Vasyl Gutnyk
1

también puedes probarlo de esta manera

var data = 22;
if (Number.isInteger(data)) {
    console.log("integer");
 }else{
     console.log("not an integer");
 }

o

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}
Adeojo Emmanuel IMM
fuente
Esto producirá el resultado incorrecto para data=22.5;. También ambas ramas tienen console.log("not an integer"):: S
Colin Breame
0

Tuve que verificar si una variable (cadena o número) es un número entero y usé esta condición:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a);
}

http://jsfiddle.net/e267369d/1/

Algunas de las otras respuestas tienen una solución similar (en parseFloatcombinación con isNaN), pero la mía debería ser más sencilla y explicarse por sí misma.


Editar: descubrí que mi método falla para las cadenas que contienen comas (como "1,2") y también me di cuenta de que en mi caso particular quiero que la función falle si una cadena no es un entero válido (debería fallar en cualquier flotante , incluso 1.0). Así que aquí está mi función Mk II:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a) && (typeof a != 'string' || (a.indexOf('.') == -1 && a.indexOf(',') == -1));
}

http://jsfiddle.net/e267369d/3/

Por supuesto, en caso de que realmente necesite la función para aceptar flotantes enteros (1.0 cosas), siempre puede eliminar la condición de punto a.indexOf('.') == -1.

jahu
fuente