Vérifiez si la variable est un nombre ou une chaîne en JavaScript


Réponses:


442

Si vous avez affaire à la notation littérale, et non les constructeurs, vous pouvez utiliser typeof :.

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

Si vous créez des nombres et des chaînes par un constructeur, comme var foo = new String("foo"), vous devez garder à l' esprit que typeofpeut revenir objectpour foo.

Peut-être qu'une méthode plus infaillible pour vérifier le type serait d'utiliser la méthode trouvée dans underscore.js (la source annotée peut être trouvée ici ),

var toString = Object.prototype.toString;

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

Cela renvoie un booléen truepour les éléments suivants:

_.isString("Jonathan"); // true
_.isString(new String("Jonathan")); // true

69
qui dit respectivement "chaîne" et "nombre"
Thilo

27
Ce n'est pas correct! Il existe deux représentations possibles d'une chaîne. alert (typeof new String ()) affichera "Object". Pire encore, javascript convertit occasionnellement des allers-retours entre les deux représentations en arrière-plan à des fins d'optimisation
George Mauer

3
@George Selon l'OP, seules les variables existantes seront testées.
Sampson

3
Bien sûr, mais disons que j'ai la fonction isString (str) {return typeof str === 'string'} certains convertis en Java peuvent utiliser ma méthode comme var myString = new String("stuff I like"); isString(myString)ceci donc cela retourne false. De plus, je ne sais pas exactement combien de temps dure la conversion backgroiund, je sais que lorsque j'appelle "hi" .length, "hi" est converti en objet, je ne sais pas combien de temps il est à nouveau converti ou s'il est lié à la variable.
George Mauer

8
Vrai, mais voudriez-vous quand même utiliser l'objet String?
Félix Saparelli

211

La meilleure façon de le faire est d'utiliser le isNaNcasting de type +:

Méthode all-in mise à jour:

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

La même chose avec 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

21
Cela ressemble à une bonne solution si vous souhaitez compter les chaînes qui analysent comme des nombres valides.
Trevor Burnham

2
FYI: nullest contraint à 0 et retourne vrai pourisNumber(null);
Edward

1
ce qui ne va pasfunction is_number(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n);}
OneOfOne

1
Cela échoue également pour une chaîne telle que «123abc».
ash

1
@ash Merci, j'ai mis à jour la solution pour couvrir également ce cas.
BitOfUniverse

73

La meilleure façon que j'ai trouvée est de vérifier une méthode sur la chaîne, c'est-à-dire:

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

ou si vous voulez faire quelque chose avec la vérification numérique d'une propriété numérique,

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

C'est un peu comme "taper du canard", c'est à vous de choisir la manière la plus logique. Je n'ai pas assez de karma pour commenter, mais typeof échoue pour les chaînes et les nombres encadrés, c'est-à-dire:

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

alertera "objet".


2
Je trouve que c'est mieux que typeofcar il peut toujours tester une chaîne, qu'elle soit primitive ou objet String. Il vous suffit de tester une méthode unique pour le type souhaité.
ADTC

Du point de vue de quelqu'un qui doit maintenir le code, choisir ce chemin peut être déroutant. "Pourquoi ont-ils utilisé une sous-chaîne et n'ont transmis aucune valeur? Quelle logique métier me manque ici?" À tout le moins, cela doit être associé à un commentaire expliquant la logique impliquée.
Lemmings19

3
@ Lemmings19 Il n'appelle pas réellement la méthode de sous-chaîne, il vérifie seulement si x a une méthode de sous-chaîne.
Alokito

1
J'aime l'idée de ce type de frappe de canard, mais cela échouera pour des choses comme {substring:"hello"}. Je sais que pour mes besoins, je viens de tester ce que l'opération spécifique que je devais faire (module) fait pour le type que je devais vérifier (sur les chaînes, le module renvoie undefined), puis j'ai vérifié cela au lieu d'obtenir son type.
Tadhg McDonald-Jensen du

30

Vous recherchez 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"));

Voir la fonction JavaScript isNaN () sur MDN.


3
Je trouve étrange qu'ils choisissent l'opération inverse pour le nom de la méthode. Semble plus intuitif d'appeler isNumber ().
Nathan Taylor

12
Ce n'est pas en fait une opération inverse de 'isNumber'. NaN est une valeur spéciale de nombre en javascript. isNaN convertit tout ce qui lui est fourni en nombre et vérifie si le résultat est NaN ou non. Pour les chaînes comme "25", vous obtenez un résultat incorrect.
Chetan Sastry

1
Je viens de tester avec "25" et il est retourné faux - comme je m'y attendais.
Jakob Gade

2
NaN est une valeur spéciale dans la norme IEEE 754 pour l'arithmétique à virgule flottante binaire, pas seulement une chose JavaScript. (Eh bien, pour être précis: "les 9007199254740990 (c'est-à-dire, (2 ^ 53) -2)" valeurs sans numéro "distinctes de la norme IEEE sont représentées dans ECMAScript comme une seule valeur NaN spéciale." )
NickFitz

2
Gardez à l'esprit que cela isNaNrevient falsepour null(mais truepour undefined).
Toni

28

Vérifiez si la valeur est un littéral de chaîne ou un objet chaîne:

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

Test de l'unité:

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

La vérification d'un numéro est similaire:

function isNumber(o) {
    return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
}

1
(o.constructor === String) semble à lui seul suffisant, même pour les littéraux de chaîne.
Chris Noe

2
Cela provoquera une exception si o === null
TJ.

3
J'ai adoré cette solution. Pour éviter l'exception cependant pour le cas nul, utilisez o ["constructeur"] au lieu de o.constructor
dreamerkumar

2
@VishalKumar C'est donc tout ce qu'il faut: function is (type, value) { return value["constructor"] === type; }?
ceving

22

Depuis ES2015, la façon correcte de vérifier si une variable contient un nombre valide est Number.isFinite(value)

Exemples:

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

1
Cela ne prend pas en charge Internet Explorer. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
davedeecoder

1
Ne fonctionne pas sur String, ce qui est la question d'origine.
Eric Grange

18

Essaye ça,

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

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

if(isInteger("1a11")) {
   console.log( 'Integer' );
} else {
   console.log( 'Non Integer' );
}
</script>

essayez '-2'. il retourne faux.
KChen

1
Pourquoi gardez-vous (ou ne modifiez-vous pas) une réponse qui ne fonctionne pas? ... Attention, un nombre négatif peut également être un entier.
Ason

13

La meilleure façon de procéder:

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

Cela satisfait les cas de test suivants:

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

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

Ou adaptez-le pour retourner un type inconnu:

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

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

Mise à jour du 12 mai 2012: exemple complet sur Javascript: un meilleur type de .


Chambre Toujours à l' amélioration en ce qui concerne realTypeOf: realTypeOf(NaN) -> "Number"qui est le même comportement que typeofconvenu , mais encore loin d' être idéale.
Max

9

Voici une approche basée sur l'idée de contraindre l'entrée à un nombre ou une chaîne en ajoutant zéro ou la chaîne nulle, puis effectuez une comparaison d'égalité typée.

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

Pour une raison insondable, x===x+0semble mieux performer que x===+x.

Y a-t-il des cas où cela échoue?

Dans la même veine:

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

Cela semble être légèrement plus rapide que l'un x===true || x===falseou l' autre typeof x==="boolean"(et beaucoup plus rapide que x===Boolean(x)).

Ensuite, il y a aussi

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

Tout cela dépend de l'existence d'une opération "d'identité" propre à chaque type qui peut être appliquée à n'importe quelle valeur et produire de manière fiable une valeur du type en question. Je ne peux pas penser à une telle opération pour les dates.

Pour NaN, il y a

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

Il s'agit essentiellement de la version de soulignement, et en l'état, elle est environ quatre fois plus rapide que isNaN(), mais les commentaires dans la source de soulignement mentionnent que "NaN est le seul nombre qui ne s'égale pas" et ajoute une vérification pour _.isNumber. Pourquoi? Quels autres objets ne s'égaleraient pas? x !== +xSoulignez également les utilisations - mais quelle différence cela pourrait- +il faire ici?

Alors pour le paranoïaque:

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

ou ca

function is_undefined(x) { return x===void(0); }

1
x! == + x essaie d'abord de convertir x en nombre.
Adrian Bartholomew

8

Pouvez-vous simplement le diviser par 1?

Je suppose que le problème serait une entrée de chaîne comme: "123ABG"

var Check = "123ABG"

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

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

Juste comme je l'ai fait récemment.


Je ne pense pas qu'il veuille que ce soit vrai si c'est une chaîne de chiffres. Peut-être utiliser ===
Curtis

7

euh, que diriez-vous juste:

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

Après un examen approfondi plusieurs mois plus tard, cela garantit uniquement objqu'un objet a le nom de méthode ou de propriété toLowerCasedéfini. J'ai honte de ma réponse. Veuillez en voir typeofun qui a été voté en premier.


7

Ou utilisez simplement l'inverseur de isNaN():

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

Et oui, utiliser jQuery $.isNumeric()est plus amusant pour l'argent.


isNaN('123')donne faux, bien que l'argument soit une chaîne numérique et non de type numérique
JustAMartin

6

Je pense que la conversion de la var en une chaîne diminue les performances, au moins ce test effectué dans les derniers navigateurs le montre.

Donc, si vous vous souciez de la performance, je le ferais, j'utiliserais ceci:

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

pour vérifier si la variable est une chaîne (même si vous utilisez var str = new String("foo"), str instanceof Stringrenvoie true).

Quant à vérifier si c'est un nombre, je choisirais le natif isNaN:; une fonction.



4

Cette solution résout bon nombre des problèmes soulevés ici!

C'est de loin la méthode la plus fiable que j'ai utilisée de loin. Je n'ai pas inventé cela et je ne me souviens pas où je l'ai trouvé à l'origine. Mais cela fonctionne là où d'autres techniques échouent:

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

Exemple d'exactitude

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"

2
Et c'est vraiment lent.

Tarazaburo, je ne sais pas où vous obtenez vos données, mais un petit benchmark est en ordre:
Michael Mikowski

Je ne trouve pas cela "vraiment lent". En testant une vitesse supérieure à 1 million d'itérations, je ne trouve pas pire que la moitié de la vitesse de la typeofméthode native (0,788 s contre 1,481 s) sur Chrome. C'est certainement une performance acceptable compte tenu des résultats améliorés. Pourquoi pensez-vous que c'est "vraiment lent?" Peut-être que c'est - dans IE6 / 7/8? Mais tout est "vraiment lent" dans ces navigateurs.
Michael Mikowski

Eh bien, je l'ai dit parce que j'avais déjà fait l'analyse comparative. Rassemblez un nouveau petit à jsperf.com/check-typeof-number-again , et typeofest 100 fois plus rapide, qu'est-ce qui me manque?

Vous manquez le fait que 3m ops / s n'est pas un problème pour la plupart du code lors de la vérification du type. Je n'appellerais pas cela "vraiment lent" par aucune mesure. Mon benchmark ressemblait à ceci: var i, k, start = + new Date (); pour (i = 0; i <1000000; i ++) {k = typeof ('foo'); k = type de (123,5); }; end = + new Date (); console.log (fin - début);
Michael Mikowski


4

typeof fonctionne très bien pour moi dans la plupart des cas. Vous pouvez essayer d'utiliser une instruction if

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

où x est un nom de variable de votre choix


Qu'est-ce que cette réponse ajoute par rapport à la plus votée?
Bartek Banachewicz

2
Simplicité et clarté?
Tim Erickson

3

la meilleure façon que j'ai trouvée qui pense aussi aux nombres positifs et négatifs est de: O'Reilly Javascript et 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;

}


3

Euh? Utilisez simplement des expressions régulières! :)

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

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

3

comme une chaîne comme «1234» avec typeof affichera «chaîne», et l'inverse ne peut jamais se produire (typeof 123 sera toujours un nombre), le mieux est d'utiliser une simple expression régulière /^\-?\d+$/.test(var). Ou plus avancé pour faire correspondre les flottants, les entiers et les nombres négatifs, /^[\-\+]?[\d]+\.?(\d+)?$/ le côté important .testest qu'il ne lèvera PAS d'exception si le var n'est pas une chaîne, la valeur peut être n'importe quoi.

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 vous cherchez le vrai type, alors seul typeof fera l'affaire.


3

@ La réponse de BitOfUniverse est bonne, et je trouve une nouvelle façon:

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

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

Je sais que ça ne 0peut pas être un dividende, mais ici la fonction fonctionne parfaitement.


2

Vérification de type

Vous pouvez vérifier le type de variable en utilisant l' typeofopérateur:

typeof variable

Vérification de la valeur

Le code ci-dessous renvoie vrai pour les nombres et faux pour toute autre chose:

!isNaN(+variable);

var variable = '123'; console.log (! isNaN (+ variable)); donne vrai bien qu'il s'agisse d'une chaîne et non d'un type
numérique

Parce que «123» est un nombre! Si vous voulez connaître le type de la variable, vous pouvez facilement utiliser l' typeofopérateur! @JustAMartin
Amir Fo

Oui, mais la question initiale était de distinguer les variables de type chaîne des variables de type numérique. «123» est toujours une chaîne. Si je passe 123, la réponse devrait être numbermais si je passe `` 123 '' ou `` abc '' ou tout autre littéral cité, c'est une chaîne, et peu importe si elle peut être analysée en nombre ou non.
JustAMartin

@JustAMartin Ok j'ai édité ma réponse.
Amir Fo

1

L'opération XOR peut être utilisée pour détecter un nombre ou une chaîne. nombre ^ 0 donnera toujours le nombre en sortie et la chaîne ^ 0 donnera 0 en sortie.

Example: 
   1)  2 ^ 0 = 2
   2)  '2' ^ 0  = 2
   3)  'Str' ^ 0 = 0

1

Simple et complet:

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

Cas de test:

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

0

Utilisez simplement

myVar.constructor == String

ou

myVar.constructor == Number

si vous souhaitez gérer des chaînes définies en tant qu'objets ou littéraux et enregistre, vous ne voulez pas utiliser une fonction d'assistance.


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

0

Très tard pour la fête; cependant, ce qui suit a toujours bien fonctionné pour moi lorsque je veux vérifier si une entrée est soit une chaîne soit un nombre en une seule fois.

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

0

Créé un jsperf sur la vérification si une variable est un nombre. Plutôt interessant! typeof a en fait une utilisation de performance. Utilisant typeofautre chose que des nombres, augmente généralement d'un tiers la vitesse variable.constructorcar la majorité des types de données en javascript sont des objets; les chiffres ne le sont pas!

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

typeof variable === 'number'| le plus rapide | si vous voulez un nombre, comme 5, et non '5'
typeof parseFloat(variable) === 'number'| le plus rapide | si vous voulez un nombre, comme 5 et '5'

isNaN()est plus lent, mais pas beaucoup plus lent. J'avais de grands espoirs parseIntet parseFloat, cependant, ils étaient horriblement plus lents.


0

Pour détecter les nombres, le passage suivant de JavaScript: The Good Parts de Douglas Crockford est pertinent:

La fonction isFinite est le meilleur moyen de déterminer si une valeur peut être utilisée comme nombre car elle rejette NaN et Infinity. Malheureusement, isFinite tentera de convertir son opérande en nombre, donc ce n'est pas un bon test si une valeur n'est pas réellement un nombre. Vous pouvez définir votre propre fonction isNumber:

var isNumber = function isNumber(value) { return typeof value === 'number' &&
            isFinite(value);
};
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.