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>

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")

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.


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
}

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;
};


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.
    }
}

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);
}

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);

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


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

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

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

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.


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

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.


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.


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');
}

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!");
}

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;
};

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.


3

Essayez ceci:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}

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

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)) )


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+''));
}


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;
};

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;

    }

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.


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);

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");
}

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.