39 votes

Une fonction isNumeric () améliorée?

Au cours de certains projets, j'ai besoin de valider certaines données et d'être aussi certain que possible, que c'est en javascript valeur numérique qui peut être utilisé dans des opérations mathématiques.

jQuery, et quelques autres bibliothèques javascript déjà inclus cette fonction, appelée généralement isNumeric. Il y a aussi un post sur stackoverflow qui a été largement accepté comme la réponse, la même routine que le ci-dessus mentionnée bibliothèques utilisent.

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

Étant mon premier post, j'ai été incapable de répondre dans ce fil. Le problème que j'ai eu avec l'acceptées post a été qu'il semble y avoir des cas particuliers qui ont affecté le travail que je faisais, et j'ai donc fait quelques modifications pour essayer de masquer le problème que j'avais.

Tout d'abord, le code ci-dessus doit retourner true si l'argument est un tableau de longueur 1, et que le seul élément d'un type réputé comme le numérique par la logique ci-dessus. À mon avis, si c'est un tableau puis son pas numérique.

Pour pallier ce problème, j'ai ajouté un chèque à l'actualisation de tableaux à partir de la logique

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}

Bien sûr, vous pouvez également utiliser Array.isArray au lieu de Object.prototype.toString.call(n) !== '[object Array]'

EDIT: j'ai modifié le code pour prendre en compte un test générique pour le tableau, ou vous pouvez utiliser jquery $.isArray ou de prototypes Object.isArray

Ma deuxième question est que c'est Négatif entier Hexadécimal de chaînes littérales ("-0xA" -> -10) n'étaient pas comptées comme du numérique. Cependant, Positif entier Hexadécimal de chaînes littérales ("0xA" -> 10) wrere traités comme numérique. J'ai besoin des deux pour être valide numérique.

J'ai ensuite modifié la logique de le prendre en compte.

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

Si vous êtes inquiet au sujet de la création de la regex chaque fois que la fonction est appelée, alors vous pourriez le réécrire à l'intérieur d'une fermeture, quelque chose comme cela

isNumber = (function () {
  var rx = /^-/;

  return function (n) {
      return Object.prototype.toString.call(n) !== '[object Array]' && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
  };
}());

J'ai alors pris le Cms +30 cas de test et cloné le test sur jsfiddle ajouté mes supplémentaire de cas de test et mon décrite ci-dessus de la solution.

Tout semble fonctionner comme prévu et je n'ai pas rencontré de problèmes. Existe-il des questions, un code ou théorique, que vous pouvez voir?

Il ne peut pas remplacer le largement acceptée/utilisé de réponse, mais si c'est ce que vous vous attendez à des résultats à partir de votre fonction isNumeric alors j'espère que ce sera de peu d'aide.

EDIT: Comme l'a souligné Bergi, il y a d'autres objets qui pourraient être considérés comme des numériques, et il serait préférable d'indiquer que la liste noire. C'est dans cet esprit que je voudrais ajouter à ces critères.

Je veux que ma fonction isNumeric de ne considérer que les Nombres ou de Chaînes de caractères

Avec cela à l'esprit, il serait préférable d'utiliser

function isNumber(n) {
  return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

Cela a été ajoutée à titre de test 22

4voto

Bergi Points 104242

À mon avis, si c'est un tableau puis son pas numérique. Pour pallier ce problème, j'ai ajouté un chèque à l'actualisation de tableaux à partir de la logique

Vous pouvez avoir ce problème avec n'importe quel autre objet, par exemple {toString:function(){return "1.2";}}. Les objets qui vous pensez étaient numérique? Number objets? Aucun?

Au lieu d'essayer de la liste noire de certaines choses qui ne parviennent pas à votre test, vous devez explicitement à la liste blanche les choses que vous voulez être numérique. Quelle est votre fonction censé obtenir, primitive des chaînes et des nombres? Puis tester exactement pour eux:

(typeof n == "string" || typeof n == "number")

1voto

Rembunator Points 1056

Si vous pouvez utiliser des expressions régulières, vous pouvez résoudre le problème:

 function (n) 
    { 
    return (Object.prototype.toString.call(n) === '[object Number]' ||
            Object.prototype.toString.call(n) === '[object String]') && 
           (typeof(n) != 'undefined')  &&  (n!=null) && 
           (/^-?\d+((.\d)?\d*(e[-]?\d)?(\d)*)$/.test(n.toString()) ||
           /^-?0x[0-9A-F]+$/.test(n.toString()));
    }
 

edit: Correction d'un problème avec les nombres hexadécimaux

0voto

Tutan Ramen Points 183
function isNumber(value){return typeof value == 'number';}

0voto

Rafael Rinaldi Points 350

Si AMD vous convient, consultez le paramètre isNumber () de mout .

0voto

jokeyrhyme Points 354

Que diriez-vous:

 function isNumber(value) {
  value = Number(value);
  return typeof value === 'number' && !isNaN(value) && isFinite(value);
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X