Comment vérifier si une variable est un entier en JavaScript?

405

Comment vérifier si une variable est un entier en JavaScript et lancer une alerte si ce n'est pas le cas? J'ai essayé, mais cela ne fonctionne pas:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>
JBa
la source
2
Une possibilité ici est d'utiliser parseInt.
Paul
2
jsben.ch/#/htLVw - une référence pour les façons courantes de le faire
EscapeNetscape
Toutes les réponses ici sont vraiment dépassées. Aujourd'hui, je vous recommande de vous en tenir à Number.isIntegerla méthode la moins hacky.
Benjamin Gruenbaum
@Benjamim que faire si le nombre est une chaîne qui peut être convertie en entier? et en HTML, tout est une chaîne .. donc Number.isInteger ("69") est faux
joedotnot

Réponses:

344

Utilisez l'opérateur === ( égalité stricte ) comme ci-dessous,

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")
pranag
la source
95
cela compte NaN comme un entier. fonctionne également moins bien contre ma méthode. jsperf.com/numbers-and-integers
Blake Regalia
2
si vous exécutez votre exemple à travers le code ci-dessus, il alerte un comme un entier et l'autre comme pas un entier, ce qui est le cas ... dans le cas de NaN, le type de NaN est également différent du type de la valeur de retour de pareInt () .....
pranag
1
pourriez-vous élaborer un peu? l '"exemple" montre seulement que l'utilisation de parseInt donne des performances moins bonnes que l'utilisation du mot-clé typeof et de l'opérateur module. mais je vois ce que vous voulez dire maintenant (NaN! = NaN)
Blake Regalia
4
@connorbode en javascript, tous les nombres ont le même type (il n'y a pas de flottant ou de double), donc 2.0 === 2comme la décimale inutile n'est qu'une représentation différente du même nombre, elle parseInt(2.0) === 2.0est donc équivalente à parseInt(2) === 2ce qui est vrai
Michael Theriot
1
@BlakeRegalia: Bien qu'étant rapide, sa méthode ne transmet pas toutes les valeurs possibles de cette réponse: stackoverflow.com/a/14794066/843732
c00000fd
506

Cela dépend, voulez-vous également convertir des chaînes en entiers potentiels?

Cela fera:

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

Avec opérations au niveau du bit

Analyse et vérification simples

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

Court-circuit et sauvegarde d'une opération d'analyse:

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

Ou peut-être les deux d'un seul coup:

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

Tests:

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

Voici le violon: http://jsfiddle.net/opfyrqwp/28/

Performance

Les tests révèlent que la solution de court-circuit présente les meilleures performances (ops / sec).

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

Voici une référence: http://jsben.ch/#/htLVw

Si vous souhaitez une forme de court-circuit plus courte et obtuse:

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

Bien sûr, je suggère de laisser le minificateur s'en occuper.

krisk
la source
4
@krisk - A voté pour plusieurs solutions. Nous avons également effectué un test rapide sur les 4 variantes que vous avez fournies: jsperf.com/tfm-is-integer - et déterminé que la solution de court-circuit présente les meilleures performances.
tfmontague
1
Il revient faux le 209999999999999999: - (
jkucharovic
1
@jkucharovic, l'opérateur OR au niveau du bit est le coupable. L'utilisation de la version non bit à bit retournera true.
krisk
1
Cela fait «2». évaluer à vrai
cyberwombat
1
@cyberwombat et bien c'est un nombre décimal 2.0 :-)
Kuba Beránek
120

En supposant que vous ne connaissiez rien de la variable en question, vous devriez adopter cette approche:

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
}

Pour le dire simplement:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}
Blake Regalia
la source
8
Que voulez-vous dire? Cela vérifie les types de données en javascript, "1.0"est une chaîne et n'est donc pas un nombre. Sinon, ce 1sera la valeur d'une variable si vous la définissez ainsi var my_var=1.0;, ce qui est correctement identifié par cette fonction comme un entier.
Blake Regalia
4
Bientôt, Number.isInteger()ça marchera ... jusque-là, c'est une bonne façon de le faire
Claudiu
Number.isInteger ne fonctionne pas pour moi. Je dois faire quelque chose de mal. La solution de Blake% 1 fonctionne parfaitement.
mcmacerson
104

Number.isInteger() semble être la voie à suivre.

MDN a également fourni le polyfill suivant pour les navigateurs ne prenant pas en charge Number.isInteger() , principalement toutes les versions d'IE.

Lien vers la page MDN

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};
Walter Roman
la source
2
MDN a retiré
Bernhard Döbler
2
C'est la réponse la plus simple et la plus «correcte». Je veux dire, JavaScript a déjà la méthode pour vérifier l'intégralité. Pas besoin d'en écrire un nouveau. isNaN () teste la numéricité, pas l'entier.
globewalldesk
66

Vous pouvez vérifier si le numéro a un reste:

var data = 22;

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

Attention, si votre entrée peut également être du texte et que vous voulez d'abord vérifier qu'elle ne l'est pas, vous pouvez d'abord vérifier le type:

var data = 22;

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

    if(data % 1 === 0){
       // yes it's an integer.
    }
}
Nan
la source
3
@Erwinus: exécutez 0 % 1 === 0dans la console. Il revient en truetant que 0 % 1retours 0.
Non
Avez-vous l'essayer dans IE ;-)
Codebeat
1
@Erwinus: 0 % 1retourne 0en mode de compatibilité IE9, IE8 et IE7.
Non
Essayez-le dans un vrai vieil IE. en plus c'est toujours un bon moyen de programmation pour vérifier zéro et ne pas se fier au navigateur pour faire quoi.
Codebeat
62
@Erwinus: Je pense que vous avez mélangé vos faits. Une erreur de division par zéro est provoquée lorsque vous divisez par zéro et non lorsque vous divisez zéro par un nombre. Rien à voir avec la version d'IE.
Non
22

Vous pouvez utiliser une expression régulière simple:

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

Tout d'abord, NaN est un "nombre" (oui je sais que c'est bizarre, roule avec), et non une "fonction".

Vous devez vérifier à la fois si le type de la variable est un nombre, et pour vérifier l'entier, j'utiliserais le module.

alert(typeof data === 'number' && data%1 == 0);
Phil
la source
2
devrait être: alert (typeof data == 'number' && (data == 0 || data% 1 == 0)); pour éviter la division par zéro.
Codebeat
19
@Erwinus 0% 1 est toujours divisé par 1.
Phil
@Phil, (0 == 0 || 0 % 1 == 0)évaluera true.
tomekwi du
Oh, en passant, 0 % 1 == 0évalue également à true! %n'est pas la division!
tomekwi
13

Soyez prudent lors de l'utilisation

num% 1

une chaîne vide ('') ou booléenne (vrai ou faux) renverra comme entier. Vous pourriez ne pas vouloir faire ça

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

Number.isInteger (données)

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

construire dans la fonction dans le navigateur. Dosnt prend en charge les anciens navigateurs

Alternatives:

Math.round(num)=== num

Cependant, Math.round () échouera également pour les chaînes vides et booléennes

Jhankar Mahbub
la source
8

Pour vérifier si un entier comme l'affiche veut:

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

notez + devant les données (convertit la chaîne en nombre) et === pour exact.

Voici quelques exemples:

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

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

data="10.2"
+data===parseInt(data)
false
user603749
la source
6
Cela semble être la solution la plus intelligente pour mon cas (où cela ne me dérange pas si c'est un entier dans une chaîne). Cependant: pourquoi ne pas y aller return (+data===parseInt(data))?
Swiss Mister
6
if(Number.isInteger(Number(data))){
    //-----
}
client
la source
1
Même commentaire que ci-dessous: non pris en charge par IE et Safari .
entrecroisé le
@crisscross Maintenant pris en charge par tout sauf IE, qui n'est un problème que si vous prenez en charge les systèmes d'exploitation hérités.
faintsignal
6

La solution pré-ECMAScript-6 la plus simple et la plus propre (qui est également suffisamment robuste pour retourner false même si une valeur non numérique telle qu'une chaîne ou null est passée à la fonction) serait la suivante:

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

La solution suivante fonctionnerait également, mais pas aussi élégante que celle ci-dessus:

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

Remarque que Math.ceil () ou Math.floor () pourrait être utilisé aussi bien (au lieu de Math.round ()) dans l'implémentation ci-dessus.

Ou bien:

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

Une solution incorrecte assez courante est la suivante:

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

Bien que cette approche basée sur parseInt fonctionne bien pour de nombreuses valeurs de x, une fois que x devient assez grand, il ne fonctionnera pas correctement. Le problème est que parseInt () contraint son premier paramètre à une chaîne avant d'analyser les chiffres. Par conséquent, une fois que le nombre devient suffisamment grand, sa représentation sous forme de chaîne sera présentée sous forme exponentielle (par exemple, 1e + 21). Par conséquent, parseInt () tentera alors d'analyser 1e + 21, mais arrêtera l'analyse quand il atteindra le caractère e et retournera donc une valeur de 1. Observez:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

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

Pourquoi personne n'a-t-il mentionné Number.isInteger() t-il ?

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

Fonctionne parfaitement pour moi et résout le problème avec le NaNdébut d'un certain nombre.

nuits
la source
1
Notez qu'il s'agit d'ES6, donc les navigateurs plus anciens (comme IE <= 11) ne le prennent pas en charge. Les documents ci-dessus fournissent un polyfill.
évêque le
Quelqu'un a mentionné Number.isInteger(), 3,5 ans avant vous: stackoverflow.com/a/27424770/5208540
Alex Stragies
si nous allons attraper une valeur à partir d'une entrée, vérifiez, Number.isInteger retournera toujours false car la valeur d'entrée est de type chaîne de données
Shinigamae
6

Dans ES6, 2 nouvelles méthodes sont ajoutées pour l'objet numérique.

La méthode Number.isInteger () y renvoie true si l'argument est un entier.

Exemple d'utilisation:

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

La norme ECMA-262 6.0 (ES6) inclut Number.isInteger fonction .

Afin d'ajouter la prise en charge de l'ancien navigateur, je recommande fortement d'utiliser une solution solide et prise en charge par la communauté de:

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

qui est une pure bibliothèque de polyfills ES6 JS .

Notez que cette bibliothèque nécessite es5-shim, suivez simplement README.md.

gavenkoa
la source
4

Vous pouvez essayer Number.isInteger(Number(value))s'il valuepeut s'agir d'un entier sous forme de chaîne, par exemple, var value = "23"et vous souhaitez que cela soit évalué true. Évitez d'essayer Number.isInteger(parseInt(value))car cela ne retournera pas toujours la valeur correcte. Par exemple, si var value = "23abc"et que vous utilisez l' parseIntimplémentation, elle retournera toujours true.

Mais si vous voulez des valeurs strictement entières, vous Number.isInteger(value)devriez probablement faire l'affaire.

gbozee
la source
1
Notez que cela n'est pas pris en charge par IE; comme indiqué ici dans le docu, mon script a été arrêté à cause de cela, surtout si le var que vous vérifiez n'est pas défini
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
la source
3
Après 29 réponses, on s'attendrait à un peu plus d'explications pour faire ressortir votre réponse ...
brasofilo
3

Vérifiez si la variable est égale à cette même variable arrondie à un entier, comme ceci:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}
Elliot Bonneville
la source
Vous pouvez très facilement résoudre le problème de cette fonction avec le retour truepour NaN, en changeant simplement !=de !==et inverser les ifblocs. Cela fonctionne parce que NaNc'est la seule valeur en JavaScript qui ne s'égale pas. Par exemple, le nouveau code devrait êtreif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99
3

Par ailleurs, Number.isInteger(). Peut Number.isSafeInteger()- être est une autre option ici en utilisant l'ES6 spécifié.

Pour polyfill Number.isSafeInteger(..)dans les navigateurs pré-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
la source
3

Number.isInteger() est le meilleur moyen si votre navigateur le prend en charge, sinon, je pense qu'il y a tellement de façons de procéder:

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

ou:

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

ou:

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

ou:

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

maintenant nous pouvons tester les résultats:

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

Donc, toutes ces méthodes fonctionnent, mais lorsque le nombre est très grand, parseInt et l'opérateur ^ ne fonctionneraient pas bien.

Charles Chu
la source
3

Essayez ceci:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}
Jan WebDev
la source
Number.isInteger () n'est pas pris en charge dans toutes les versions des navigateurs IE.
SKR
2

Vous pouvez utiliser cette fonction:

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

Il retournera vrai même si la valeur est une chaîne contenant une valeur entière.
Ainsi, les résultats seront:

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

Mon approche:

a >= 1e+21Le test ne peut réussir que pour une valeur qui doit être un nombre et une très grande. Cela couvrira tous les cas à coup sûr, contrairement aux autres solutions qui ont été fournies dans cette discussion.

a === (a|0)Si l'argument de la fonction donnée est exactement (===) identique à la valeur transformée au niveau du bit, cela signifie que l'argument est un entier.

a|0retournera 0pour toute valeur aqui n'est pas un nombre , et s'il as'agit bien d'un nombre, il supprimera tout ce qui est après la virgule décimale, 1.0001deviendra donc1

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
la source
1
Bonne idée! J'aime aussi que vous ayez montré vos tests mais malheureusement cela ne considère pas une valeur de chaîne de "0".
Jammer
Hé @vsync, pas intentionnellement. J'ai fait à l'origine un vote positif, mais j'ai décidé de revenir en arrière en raison de mon commentaire précédent. Je dois avoir accidentellement double-cliqué dessus ou quelque chose.
Jammer
1

Vous pouvez utiliser regexp pour cela:

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

Utilisez l' |opérateur:

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

Ainsi, une fonction de test pourrait ressembler à ceci:

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

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

  return true;
};
Golo Roden
la source
1

Cela résoudra un autre scénario ( 121. ), un point à la fin

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
la source
1

Pour les valeurs entières positives sans séparateurs:

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

Teste 1. s'il n'est pas vide et 2. si la valeur est égale au résultat du remplacement d'un caractère non numérique dans sa valeur.

DanielL
la source
1

Ok eu moins, car n'a pas décrit mon exemple, donc plus d'exemples :):

J'utilise l'expression régulière et la méthode de test:

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
la source
Got moins probablement parce que le test n'est pas une fonction.
imlokesh
@imlokesh que voulez-vous dire "n'est pas une fonction"? oO j'ai écrit j'utilise "méthode de test".
Vasyl Gutnyk
@imlokesh pas de problème, je demande simplement à U car je l'ai utilisé en production :) et je pensais que vous
avez
1

vous pouvez également l'essayer de cette façon

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

ou

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}
Adeojo Emmanuel IMM
la source
Cela produira le mauvais résultat pour data=22.5;. De plus, les deux succursales ont console.log("not an integer"):: S
Colin Breame
0

J'ai dû vérifier si une variable (chaîne ou nombre) est un entier et j'ai utilisé cette condition:

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

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

Certaines des autres réponses ont une solution similaire (compter sur parseFloatcombiné avec isNaN), mais la mienne devrait être plus simple et s'expliquer d'elle-même.


Edit: j'ai découvert que ma méthode échoue pour les chaînes contenant des virgules (comme "1,2") et j'ai également réalisé que dans mon cas particulier, je veux que la fonction échoue si une chaîne n'est pas un entier valide (devrait échouer sur n'importe quel flottant , même 1.0). Voici donc ma fonction 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/

Bien sûr, si vous avez réellement besoin de la fonction pour accepter des flottants entiers (1.0), vous pouvez toujours supprimer la condition de point a.indexOf('.') == -1.

jahu
la source