La classe `Number` en JavaScript

La classe `Number` en JavaScript

Cet article explique la classe Number en JavaScript.

Nous expliquerons en détail les caractéristiques de Number, les pièges courants, les API utiles et des exemples pratiques étape par étape.

YouTube Video

La classe Number en JavaScript

Number est le type numérique fondamental en JavaScript et est représenté comme un nombre à virgule flottante double précision IEEE-754 (64 bits).

Bases : Représentation des nombres et vérification du type

En JavaScript, tous les nombres sont représentés comme le type primitif number.

 1// Primitive numbers and Number object
 2const a = 42;                 // primitive number
 3const b = 3.14;               // primitive float
 4const c = Number(10);         // primitive via constructor call (function form)
 5const d = new Number(10);     // Number object (wrapper)
 6
 7console.log(typeof a);        // "number"
 8console.log(typeof d);        // "object"
 9console.log(c == d);          // true  (value coerces)
10console.log(c === d);         // false (different types)
  • Ce code démontre la différence entre un type primitif number et l'objet wrapper Number. Normalement, on utilise les types primitifs au lieu des objets d'encapsulation.

Valeurs spéciales : NaN, Infinity et constantes

Number fournit des valeurs spéciales (NaN, Infinity) et des constantes.

 1// Special numeric values and constants
 2console.log(Number.NaN);                 // NaN
 3console.log(Number.POSITIVE_INFINITY);   // Infinity
 4console.log(Number.NEGATIVE_INFINITY);   // -Infinity
 5
 6console.log(Number.MAX_VALUE);           // largest positive representable
 7console.log(Number.MIN_VALUE);           // smallest positive representable (closest to 0)
 8console.log(Number.MAX_SAFE_INTEGER);    // 9007199254740991
 9console.log(Number.MIN_SAFE_INTEGER);    // -9007199254740991
10console.log(Number.EPSILON);             // smallest difference ~2.220446049250313e-16
  • Les entiers supérieurs ou égaux à MAX_SAFE_INTEGER peuvent ne pas être représentés avec précision. Utilisez BigInt si la précision est requise. EPSILON est utilisé pour les comparaisons de nombres à virgule flottante.

Conversion de nombres : Number(), parseInt, parseFloat et opérateur +

Il existe plusieurs manières de convertir une chaîne de caractères en nombre, chacune ayant des comportements différents.

 1// Converting strings to numbers
 2console.log(Number("42"));        // 42
 3console.log(Number("  3.14 "));   // 3.14
 4console.log(+ "7");               // 7 (unary +)
 5
 6console.log(parseInt("42px"));    // 42
 7console.log(parseFloat("3.14abc"));// 3.14
 8
 9// Careful with parseInt and radix
10console.log(parseInt("08"));      // 8
11console.log(parseInt("08", 10));  // 8 (explicit radix is safer)
  • Number() renvoie NaN à moins que toute la chaîne soit strictement au format numérique, tandis que parseInt et parseFloat analysent la partie numérique interprétable dès le début de la chaîne. Il est plus sûr de toujours préciser la base (radix) lors de l’utilisation de parseInt.

Gestion et vérification de NaN : isNaN et Number.isNaN

NaN (Not-A-Number) est particulier car NaN !== NaN. Il existe des différences dans leur façon de vérifier : isNaN (global) effectue une conversion de type et peut donner de faux positifs, donc il est recommandé d'utiliser Number.isNaN.

1// NaN detection differences
2console.log(NaN === NaN);             // false
3
4console.log(isNaN("foo"));            // true  -> because "foo" coerces to NaN
5console.log(Number.isNaN("foo"));     // false -> "foo" is not the numeric NaN
6
7console.log(Number.isNaN(NaN));       // true
  • Utilisez Number.isNaN pour vérifier les nombres et valider les résultats de calcul afin d’éviter les conversions de type inutiles.

Erreurs de virgule flottante et comparaisons en utilisant Number.EPSILON

En raison de la norme IEEE-754, des erreurs telles que 0.1 + 0.2 !== 0.3 peuvent se produire. Pour des comparaisons strictes, il est courant d'utiliser la différence et Number.EPSILON.

1// Floating point precision example and EPSILON comparison
2const sum = 0.1 + 0.2;
3console.log(sum === 0.3);             // false
4
5function nearlyEqual(a, b, epsilon = Number.EPSILON) {
6  return Math.abs(a - b) <= epsilon * Math.max(1, Math.abs(a), Math.abs(b));
7}
8
9console.log(nearlyEqual(sum, 0.3));   // true
  • Lorsque vous admettez des erreurs lors de la comparaison, il est recommandé d'utiliser une implémentation robuste telle que nearlyEqual, qui effectue également une mise à l'échelle en plus de la différence absolue.

Vérification des entiers et des entiers sûrs (isInteger, isSafeInteger)

Il existe des API pour vérifier si une valeur est un entier et si elle est dans la plage des entiers sûrs.

1// Integer and safe integer checks
2console.log(Number.isInteger(3));                 // true
3console.log(Number.isInteger(3.0));               // true
4console.log(Number.isInteger(3.1));               // false
5
6console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true
7console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
  • Lorsque la précision des grands entiers est nécessaire, utilisez Number.isSafeInteger pour vérifier, et envisagez d'utiliser BigInt pour les nombres dépassant cette plage.

Affichage et formatage : toFixed, toPrecision, toString

Il existe des méthodes disponibles pour contrôler l'affichage des nombres. toFixed renvoie une chaîne avec un nombre de décimales spécifié, mais attention à l'arrondi.

1// Formatting numbers for display
2const x = 1.23456;
3console.log(x.toFixed(2));         // "1.23"   (string)
4console.log(x.toPrecision(3));     // "1.23"   (string with total significant digits)
5console.log((255).toString(16));   // "ff"     (hexadecimal string)
  • toFixed renvoie une chaîne, donc veillez à la conversion en nombre avant de faire des calculs avec la valeur.

Précautions concernant la concaténation de chaînes et l'opérateur +

L'opérateur + sert à la fois pour l'addition numérique et la concaténation de chaînes, donc des résultats inattendus peuvent survenir selon les types de données impliqués.

1// Pitfall with + operator and type coercion
2console.log(1 + 2 + "px");    // "3px"
3console.log("px" + 1 + 2);    // "px12"
4console.log(1 + "2" - 0);     // 3  (string coerced to number for subtraction)
  • Lorsque des chaînes et des nombres sont mélangés, il est plus sûr d'utiliser explicitement String(), Number() ou les templates littéraux pour éviter les conversions de type implicites.

Utilisations avancées : Number.parseInt / Number.parseFloat, valueOf

Number.parseInt et Number.parseFloat sont des alias des fonctions globales. valueOf est utilisé pour récupérer la valeur primitive d'un objet Number, mais c'est rarement nécessaire en pratique.

1// Number.parseInt/parseFloat aliases and valueOf example
2console.log(Number.parseInt("100", 10));   // 100
3console.log(Number.parseFloat("3.14"));    // 3.14
4
5const nObj = new Number(5);
6console.log(nObj.valueOf());               // 5
7console.log(nObj + 1);                     // 6  (object coerced to primitive)
  • Lors de l'utilisation de Number.parseInt et Number.parseFloat, faites attention à la base (radix) et à l'élagage de l'entrée. Les objets d'encapsulation sont généralement à éviter.

Référence : Petit exemple d'utilitaire - Fonctions de validation de nombre

Voici de petites fonctions utilitaires regroupant des vérifications courantes. Cela facilite des tâches comme la validation des entrées.

 1// Small number utility functions
 2function toNumberStrict(value) {
 3  // Return a Number or throw for invalid numeric strings
 4  const n = Number(value);
 5  if (typeof value === "string" && value.trim() === "") {
 6    throw new Error("Empty string is not a valid number");
 7  }
 8  if (Number.isNaN(n)) {
 9    throw new Error(`Invalid number: ${value}`);
10  }
11  return n;
12}
13
14function almostEqual(a, b, eps = Number.EPSILON) {
15  // Robust relative comparison
16  return Math.abs(a - b) <= eps * Math.max(1, Math.abs(a), Math.abs(b));
17}
  • Ce sont des fonctions très polyvalentes qui peuvent être réutilisées pour le traitement et la comparaison des entrées. Les implémentations qui lèvent des erreurs sont utiles à des fins de validation.

Résumé des performances et bonnes pratiques

Voici quelques points pratiques lors de l'utilisation de Number.

  • En principe, utilisez le type primitif number et évitez new Number().
  • Choisissez entre Number() (strict) ou parseInt/parseFloat (extraction partielle) pour la conversion chaîne-vers-nombre selon votre cas d'utilisation.
  • Utilisez Number.isNaN et Number.isFinite pour une vérification fiable.
  • Pour les comparaisons de nombres à virgule flottante, utilisez Number.EPSILON ou créez une fonction de comparaison dédiée.
  • Lorsque la précision des entiers est nécessaire, utilisez Number.isSafeInteger, et si la plage est dépassée, utilisez BigInt.
  • Vous pouvez utiliser toFixed ou toPrecision pour l'arrondi à l'affichage, mais notez que la valeur retournée est une chaîne de caractères.

Résumé

Number est le type de base pour tous les nombres en JavaScript, y compris les entiers, les décimaux et les valeurs spéciales (NaN et Infinity). Il est important d'être conscient des conversions de type et des erreurs de virgule flottante, et d'utiliser correctement des méthodes telles que Number.isNaN et Number.EPSILON. Si la plage des entiers sûrs est dépassée, utilisez BigInt, et utilisez toFixed ou toPrecision pour l'arrondi et l'affichage.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video