Après l'étude des chaînes de caractères et des regex, il est temps de
passer aux données numériques !
La gestion des données numériques en JavaScript est assez limitée mais elle
existe quand même et se fait essentiellement par le biais des
objetsNumber
etMath
. Le
premier est assez inintéressant mais il est bon de savoir à quoi il sert et ce qu'il permet de faire ; le deuxième
est une véritable boîte à outils qui vous servira probablement un jour ou l'autre.
L'objetNumber
est à la
base de tout nombre et pourtant on ne s'en sert quasiment jamais de manière explicite, car on lui préfère (comme
pour la plupart des objets) l'utilisation de son type primitif. Cet objet possède pourtant des fonctions
intéressantes comme, par exemple, celle permettant de faire des conversions depuis une chaîne de caractères jusqu'à
un nombre en instanciant un nouvel objetNumber
:
var myNumber = new Number('3'); // La chaîne de caractères « 3 » est convertie en un nombre de valeur 3
Cependant, cette conversion est
imprécise dans le sens où on ne sait pas si on obtiendra un nombre entier ou flottant en retour. On lui préfère donc
les fonctionsparseInt()
etparseFloat()
qui
permettent d'être sûr de ce que l'on obtiendra. De plus,parseInt()
utilise
un second argument permettant de spécifier la base (2 pour le système binaire, 10 pour le système décimal, etc.) du
nombre écrit dans la chaîne de caractères, ce qui permet de lever tout soupçon sur le résultat obtenu.
Cet objet possède des propriétés accessibles directement sans aucune instanciation (on appelle cela des propriétés propres à l'objet constructeur). Elles sont au nombre de cinq, et sont données ici à titre informatif, car leur usage est peu courant :
NaN
: vous connaissez déjà cette propriété qui signifie Not A
Number et qui permet, généralement, d'identifier l'échec d'une conversion de chaîne de caractères en un
nombre. À noter que cette propriété est aussi disponible dans l'espace global. Passer par
l'objetNumber
pour y accéder n'a donc que peu d'intérêt, surtout
qu'il est bien rare d'utiliser cette propriété, car on lui préfère la
fonctionisNaN()
, plus fiable.
MAX_VALUE
: cette propriété représente le nombre maximum pouvant
être stocké dans une variable en JavaScript. Cette constante peut changer selon la version du JavaScript
utilisée.
MIN_VALUE
: identique à la
constanteMAX_VALUE
sauf que là il s'agit de la valeur minimale.
POSITIVE_INFINITY
: il s'agit ici d'une constante représentant
l'infini positif. Vous pouvez l'obtenir en résultat d'un calcul si vous divisez une valeur positive par 0.
Cependant, son utilisation est rare, car on lui préfère la fonctionisFinite()
,
plus fiable.
NEGATIVE_INFINITY
: identique
àPOSITIVE_INFINITY
sauf que là il s'agit de l'infini négatif. Vous
pouvez obtenir cette constante en résultat d'un calcul si vous divisez une valeur négative par 0.
Passons donc aux essais :
var max = Number.MAX_VALUE, // Comme vous pouvez le constater, nous n'instancions pas d'objet, comme pour un accès au « prototype »
inf = Number.POSITIVE_INFINITY;
if (max < inf) {
alert("La valeur maximum est inférieure à l'infini ! Surprenant, n'est-ce pas ?");
}
Du côté des méthodes,
l'objetNumber
n'est pas bien plus intéressant, car toutes les méthodes
qu'il possède sont déjà supportées par l'objetMath
. Nous allons donc
faire l'impasse dessus.
Après une première sous-partie assez peu intéressante, nous passons enfin à
l'objetMath
qui va réellement nous servir ! Tout d'abord, deux petites
choses :
La liste des propriétés et méthodes ne sera pas exhaustive, consultez la documentation si vous souhaitez tout connaître ;
Toutes les propriétés et méthodes de cet objet sont accessibles directement sans aucune instanciation, on appelle cela des méthodes et des propriétés statiques. Considérez donc cet objet plutôt comme un namespace.
Les propriétés de
l'objetMath
sont des constantes qui définissent certaines valeurs
mathématiques comme le nombre pi (π) ou le nombre d'Euler (e). Nous ne parlons que de ces deux constantes car les
autres ne sont pas souvent utilisées en JavaScript. Pour les utiliser, rien de bien compliqué :
alert(Math.PI); // Affiche la valeur du nombre pi
alert(Math.E); // Affiche la valeur du nombre d'Euler
Voilà tout, les propriétés de
l'objetMath
ne sont pas bien dures à utiliser donc il n'y a pas
grand-chose à vous apprendre dessus. En revanche, les méthodes sont nettement plus intéressantes !
L'objetMath
comporte de nombreuses méthodes permettant de faire divers
calculs un peu plus évolués qu'une simple division. Il existe des méthodes pour le calcul des cosinus et sinus, des
méthodes d'arrondi et de troncature, etc. Elles sont assez nombreuses pour faire bon nombre d'applications
pratiques.
Vous aurez souvent besoin d'arrondir vos nombres en JavaScript,
notamment si vous faites des animations. Il est par exemple impossible de dire à un élément HTML qu'il fait 23,33
pixels de largeur, il faut un nombre entier. C'est pourquoi nous allons aborder les
méthodesfloor()
,ceil()
etround()
.
La méthodefloor()
retourne
le plus grand entier inférieur ou égal à la valeur que vous avez passée en paramètre :
Math.floor(33.15); // Retourne : 33
Math.floor(33.95); // Retourne : 33
Math.floor(34); // Retourne : 34
Concernant la
méthodeceil()
, celle-ci retourne le plus petit entier supérieur ou
égal à la valeur que vous avez passée en paramètre :
Math.ceil(33.15); // Retourne : 34
Math.ceil(33.95); // Retourne : 34
Math.ceil(34); // Retourne : 34
Et pour finir, la
méthoderound()
qui fait un arrondi tout bête :
Math.round(33.15); // Retourne : 33
Math.round(33.95); // Retourne : 34
Math.round(34); // Retourne : 34
Bien que le calcul d'une puissance puisse paraître bien simple à
coder, il existe une méthode permettant d'aller plus rapidement, celle-ci se
nommepow()
et s'utilise de cette manière :
Math.pow(3, 2); // Le premier paramètre est la base, le deuxième est l'exposant
// Ce calcul donne donc : 3 * 3 = 9
Concernant le calcul de la racine
carrée d'un nombre, il existe aussi une méthode prévue pour cela, elle se
nommesqrt()
(abréviation de square root) :
Math.sqrt(9); // Retourne : 3
Lorsqu'on souhaite faire des calculs en rapport avec les angles, on a
souvent recours aux fonctions cosinus et sinus. L'objetMath
possède
des méthodes qui remplissent exactement le même rôle
:cos()
etsin()
(il
existe bien entendu les
méthodesacos()
etasin()
).
Leur utilisation est, encore une fois, très simple :
Math.cos(Math.PI); // Retourne : -1
Math.sin(Math.PI); // Retourne : environ 0
Les résultats obtenus sont exprimés en radians.
Voici deux méthodes qui peuvent se révéler bien utiles
:max()
etmin()
. Elles
permettent respectivement de retrouver les valeurs maximum et minimum dans une liste de nombres, qu'importe si les
nombres sont dans un ordre croissant, décroissant ou aléatoire. Ces deux méthodes prennent autant de paramètres que
de nombres à comparer :
Math.max(42, 4, 38, 1337, 105); // Retourne : 1337
Math.min(42, 4, 38, 1337, 105); // Retourne : 4
Il est toujours intéressant de savoir comment choisir un nombre
aléatoire pour chaque langage que l'on utilise, cela finit toujours par servir un jour où l'autre. En JavaScript, la
méthode qui s'occupe de ça est nomméerandom()
(pour faire original).
Cette fonction est utile mais n'est malheureusement pas très pratique à utiliser comparativement à celle présente,
par exemple, en PHP.
En PHP, il est possible de définir entre quels nombres doit être choisi le nombre aléatoire. En JavaScript, un nombre décimal aléatoire est choisi entre 0 (inclus) et 1 (exclu), ce qui nous oblige à faire de petits calculs par la suite pour obtenir un nombre entre une valeur minimum et maximum.
Venons-en à l'exemple :
alert(Math.random()); // Retourne un nombre compris entre 0 et 1
Là, notre script est un peu limité du coup, la solution est donc de créer notre propre fonction qui va gérer les nombres minimum (inclus) et maximum (exclu) :
function rand(min, max, integer) {
if (!integer) {
return Math.random() * (max - min) + min;
} else {
return Math.floor(Math.random() * (max - min + 1) + min);
}
}
Et voilà une fonction prête à être utilisée ! Le troisième paramètre sert à définir si l'on souhaite obtenir un nombre entier ou non.
Essayer une adaptation de ce
code
Cette fonction est assez simple en terme de réflexion : on prend le nombre minimum que l'on soustrait au maximum, on obtient alors l'intervalle de valeur qui n'a plus qu'à être multiplié au nombre aléatoire (qui est compris entre 0 et 1), le résultat obtenu sera alors compris entre 0 et la valeur de l'intervalle, il ne reste alors plus qu'à lui ajouter le nombre minimum pour obtenir une valeur comprise entre notre minimum et notre maximum !
Bien que les
objetsNumber
etMath
implémentent
l'essentiel des méthodes de gestion des données numériques qui existent en JavaScript, certaines fonctions globales
permettent de faire quelques conversions et contrôles de données un peu plus poussés.
Si vous avez lu tous les chapitres précédents (ce que vous devriez avoir fait), vous avez normalement déjà vu ces deux fonctions, mais nous allons revoir leur utilisation dans le doute.
Ces deux fonctions se
nommentparseInt()
etparseFloat()
,
elles permettent de convertir une chaîne de caractères en un nombre. La première possède deux arguments tandis que
la seconde en possède un seul :
Le premier
argument est obligatoire, il s'agit de la chaîne de caractère à convertir en nombre. Exemple
:"303"
donnera le nombre 303 en sortie.
Le deuxième
argument est facultatif, mais il est très fortement conseillé de s'en servir avec la
fonctionparseInt()
(puisque, de toute manière, il n'existe pas
avecparseFloat()
). Il permet de spécifier la base que le nombre
utilise dans la chaîne de caractères. Exemple : 10 pour spécifier le système décimal, 2 pour le système
binaire.
L'importance du deuxième argument est simple à démontrer avec un exemple :
var myString = '08';
alert(parseInt(myString)); // Affiche : 0
alert(parseInt(myString, 10)); // Affiche : 8
Alors pourquoi cette différence de
résultat ? La solution est simple : en l'absence d'un second argument, les
fonctionsparseInt()
etparseFloat()
vont
tenter de deviner la base utilisée — et donc le système de numération associé — par le nombre écrit dans la chaîne
de caractères. Ici, la chaîne de caractères commence par un 0, ce qui est caractéristique du système octal,
on obtient donc 0 en retour. Afin d'éviter d'éventuelles conversions hasardeuses, il est toujours bon de spécifier
le système de numération de travail.
Vous souvenez-vous des
valeursNaN
etInfinity
?
Nous avions parlé de deux fonctions permettant de vérifier la présence de ces deux valeurs ; les voici
:isNaN()
qui permet de savoir si notre variable contient un nombre
etisFinite()
qui permet de déterminer si le nombre est fini.
isNaN()
renvoietrue
si
la variable ne contient pas de nombre, elle s'utilise de cette manière :
var myNumber = parseInt("test"); // Notre conversion sera un échec et renverra « NaN »
alert(isNaN(myNumber)); // Affiche « true », cette variable ne contient pas de nombre
Quant
àisFinite()
, cette fonction
renvoietrue
si le nombre ne tend pas vers l'infini :
var myNumber = 1/0; // 1 divisé par 0 tend vers l'infini
alert(isFinite(myNumber)); // Affiche « false », ce nombre tend vers l'infini
Mais pourquoi utiliser ces deux fonctions ? Je n'ai qu'à vérifier
si ma variable contient la
valeurNaN
ouInfinity
…
Admettons que vous fassiez cela ! Essayons le cas
deNaN
:
var myVar = "test";
if (myVar == NaN) {
alert('Cette variable ne contient pas de nombre.');
} else {
alert('Cette variable contient un nombre.');
}
Voyez-vous le problème ? Cette
variable ne contient pas de nombre, mais ce code croit pourtant que c'est le cas. Cela est dû au fait que l'on ne
fait que tester la présence de la valeurNaN
. Or elle est présente
uniquement si la tentative d'écriture d'un nombre a échoué (une conversion loupée par exemple), elle ne sera jamais
présente si la variable était destinée à contenir autre chose qu'un nombre.
Un autre facteur important aussi, c'est que la
valeurNaN
n'est pas égale à elle-même !
alert(NaN == NaN); // Affiche : « false »
Bref, la
fonctionisNaN()
est utile car elle vérifie si votre variable était
destinée à contenir un nombre et vérifie ensuite que ce nombre ne possède pas la
valeurNaN
.
ConcernantisFinite()
, un nombre peut tendre soit vers l'infini
positif, soit vers l'infini négatif. Une condition de ce genre ne peut donc pas fonctionner :
var myNumber = -1 / 0;
if (myNumber == Number.POSITIVE_INFINITY) {
alert("Ce nombre tend vers l'infini.");
} else {
alert("Ce nombre ne tend pas vers l'infini.");
}
Ce code est faux, on ne fait que
tester si notre nombre tend vers l'infini positif, alors que la fonctionisFinite()
se
charge de tester aussi si le nombre tend vers l'infini négatif.
Un objet
possède parfois des propriétés issues du constructeur. C'est le cas de
l'objetNumber
, avec des propriétés
commeNumber.MAX_VALUE
ouNumber.NaN
.
De même
queNumber
,
l'objetMath
possède ce genre de propriétés. Utiliser π est alors
simple :Math.PI
.
Il faut
privilégierparseInt()
etparseFloat()
pour
convertir une chaîne de caractères en un nombre.
L'usage des
propriétés de l'objetNumber
lors de tests est déconseillé : il
vaut mieux utiliser les fonctions globales prévues à cet effet, comme par
exempleisNaN()
au lieu deNaN
.