Nous connaissons de nombreux opérateurs de l'école. Ce sont des choses comme l'addition +
, la multiplication *
, la soustraction -
, etc.
Dans ce chapitre, nous commencerons par des opérateurs simples, puis nous concentrerons sur les aspects spécifiques à JavaScript, non couverts par l'arithmétique scolaire.
Avant de continuer, apprenons quelques termes courants.
Un opérande – c'est à quoi les opérateurs sont appliqués. Par exemple, dans la multiplication de 5 * 2
il y a deux opérandes : l'opérande de gauche est 5
et l'opérande de droite est 2
. Parfois, les gens appellent ces « arguments » au lieu d’« opérandes ».
Un opérateur est unaire s’il n’a qu’un seul opérande. Par exemple, la négation unaire -
inverse le signe d'un nombre :
soit x = 1 ; x = -x ; alerte( x ); // -1, la négation unaire a été appliquée
Un opérateur est binaire s’il comporte deux opérandes. Le même moins existe également sous forme binaire :
soit x = 1, y = 3 ; alerte( y - x ); // 2, le moins binaire soustrait les valeurs
Formellement, dans les exemples ci-dessus, nous avons deux opérateurs différents qui partagent le même symbole : l'opérateur de négation, un opérateur unaire qui inverse le signe, et l'opérateur de soustraction, un opérateur binaire qui soustrait un nombre d'un autre.
Les opérations mathématiques suivantes sont prises en charge :
Ajout +
,
Soustraction -
,
Multiplications *
,
Division /
,
%
restant,
Exponentiation **
.
Les quatre premiers sont simples, tandis que %
et **
nécessitent quelques mots à leur sujet.
L'opérateur reste %
, malgré son apparence, n'est pas lié aux pourcentages.
Le résultat de a % b
est le reste de la division entière de a
par b
.
Par exemple:
alerte( 5 % 2 ); // 1, le reste de 5 divisé par 2 alerte( 8 % 3 ); // 2, le reste de 8 divisé par 3 alerte( 8 % 4 ); // 0, le reste de 8 divisé par 4
L'opérateur d'exponentiation a ** b
élève a
à la puissance b
.
En mathématiques scolaires, nous écrivons cela sous la forme a b .
Par exemple:
alerte( 2 ** 2 ); // 2² = 4 alerte( 2 ** 3 ); // 2³ = 8 alerte( 2 ** 4 ); // 2⁴ = 16
Tout comme en mathématiques, l'opérateur d'exponentiation est également défini pour les nombres non entiers.
Par exemple, une racine carrée est une exponentiation de ½ :
alerte( 4 ** (1/2) ); // 2 (la puissance de 1/2 équivaut à une racine carrée) alerte( 8 ** (1/3) ); // 2 (la puissance de 1/3 équivaut à une racine cubique)
Découvrons les fonctionnalités des opérateurs JavaScript qui vont au-delà de l'arithmétique scolaire.
Habituellement, l'opérateur plus +
additionne les nombres.
Mais, si le +
binaire est appliqué aux chaînes, il les fusionne (concatène) :
soit s = "mon" + "chaîne" ; alerte(s) ; // machaîne
Notez que si l’un des opérandes est une chaîne, l’autre est également converti en chaîne.
Par exemple:
alerte( '1' + 2 ); // "12" alerte( 2 + '1' ); // "21"
Vous voyez, peu importe que le premier opérande soit une chaîne ou le second.
Voici un exemple plus complexe :
alerte(2 + 2 + '1' ); // "41" et non "221"
Ici, les opérateurs travaillent les uns après les autres. Le premier +
additionne deux nombres, donc il renvoie 4
, puis le suivant +
y ajoute la chaîne 1
, donc c'est comme 4 + '1' = '41'
.
alerte('1' + 2 + 2); // "122" et non "14"
Ici, le premier opérande est une chaîne, le compilateur traite également les deux autres opérandes comme des chaînes. Le 2
est concaténé à '1'
, donc c'est comme '1' + 2 = "12"
et "12" + 2 = "122"
.
Le binaire +
est le seul opérateur qui prend en charge les chaînes de cette manière. D'autres opérateurs arithmétiques fonctionnent uniquement avec des nombres et convertissent toujours leurs opérandes en nombres.
Voici la démo pour la soustraction et la division :
alerte( 6 - '2' ); // 4, convertit '2' en nombre alerte( '6' / '2' ); // 3, convertit les deux opérandes en nombres
Le plus +
existe sous deux formes : la forme binaire que nous avons utilisée ci-dessus et la forme unaire.
Le plus unaire ou, en d’autres termes, l’opérateur plus +
appliqué à une seule valeur, n’a aucun effet sur les nombres. Mais si l’opérande n’est pas un nombre, le plus unaire le convertit en nombre.
Par exemple:
// Aucun effet sur les nombres soit x = 1 ; alerte( +x ); // 1 soit y = -2 ; alerte( +y ); // -2 // Convertit les non-nombres alerte( +true ); // 1 alerte( +"" ); // 0
Il fait en fait la même chose que Number(...)
, mais est plus court.
Le besoin de convertir des chaînes en nombres se pose très souvent. Par exemple, si nous obtenons des valeurs à partir de champs de formulaire HTML, il s'agit généralement de chaînes. Et si on voulait les additionner ?
Le plus binaire les ajouterait sous forme de chaînes :
laissez pommes = "2" ; soit oranges = "3" ; alerte( pommes + oranges ); // "23", le binaire plus concatène les chaînes
Si nous voulons les traiter comme des nombres, nous devons les convertir puis les additionner :
laissez pommes = "2" ; soit oranges = "3" ; // les deux valeurs sont converties en nombres avant le binaire plus alerte( +pommes + +oranges ); // 5 // la variante la plus longue // alert( Nombre(pommes) + Nombre(oranges) ); // 5
Du point de vue d'un mathématicien, l'abondance des avantages peut sembler étrange. Mais du point de vue d'un programmeur, il n'y a rien de spécial : les plus unaires sont appliqués en premier, ils convertissent les chaînes en nombres, puis le plus binaire les résume.
Pourquoi les plus unaires sont-ils appliqués aux valeurs avant les valeurs binaires ? Comme nous allons le voir, cela est dû à leur priorité plus élevée .
Si une expression a plus d'un opérateur, l'ordre d'exécution est défini par leur priorité ou, en d'autres termes, l'ordre de priorité par défaut des opérateurs.
Depuis l'école, nous savons tous que la multiplication dans l'expression 1 + 2 * 2
doit être calculée avant l'addition. C'est exactement la priorité. On dit que la multiplication a une priorité plus élevée que l’addition.
Les parenthèses remplacent toute priorité, donc si nous ne sommes pas satisfaits de l'ordre par défaut, nous pouvons les utiliser pour le modifier. Par exemple, écrivez (1 + 2) * 2
.
Il existe de nombreux opérateurs en JavaScript. Chaque opérateur a un numéro de priorité correspondant. Celui avec le plus grand nombre s’exécute en premier. Si la priorité est la même, l'ordre d'exécution se fait de gauche à droite.
Voici un extrait de la table de priorité (vous n'avez pas besoin de vous en souvenir, mais notez que les opérateurs unaires sont supérieurs aux opérateurs binaires correspondants) :
Priorité | Nom | Signe |
---|---|---|
… | … | … |
14 | unaire plus | + |
14 | négation unaire | - |
13 | exponentiation | ** |
12 | multiplication | * |
12 | division | / |
11 | ajout | + |
11 | soustraction | - |
… | … | … |
2 | affectation | = |
… | … | … |
Comme on peut le voir, le « plus unaire » a une priorité de 14
qui est supérieure au 11
de « l'addition » (plus binaire). C'est pourquoi, dans l'expression "+apples + +oranges"
, les plus unaires fonctionnent avant l'addition.
Notons qu'une affectation =
est aussi un opérateur. Il est répertorié dans le tableau de priorité avec la très faible priorité de 2
.
C'est pourquoi, lorsque nous attribuons une variable, comme x = 2 * 2 + 1
, les calculs sont effectués en premier, puis le =
est évalué, stockant le résultat dans x
.
soit x = 2 * 2 + 1 ; alerte( x ); // 5
Le fait que =
soit un opérateur et non une construction de langage « magique » a une implication intéressante.
Tous les opérateurs en JavaScript renvoient une valeur. C'est évident pour +
et -
, mais aussi vrai pour =
.
L'appel x = value
écrit la value
dans x
puis la renvoie .
Voici une démo qui utilise une affectation dans le cadre d'une expression plus complexe :
soit a = 1 ; soit b = 2; soit c = 3 - (a = b + 1) ; alerte( une ); // 3 alerte( c ); // 0
Dans l'exemple ci-dessus, le résultat de l'expression (a = b + 1)
est la valeur qui a été attribuée à a
(c'est-à-dire 3
). Il est ensuite utilisé pour des évaluations ultérieures.
C'est drôle de code, n'est-ce pas ? Nous devons comprendre comment cela fonctionne, car nous le voyons parfois dans les bibliothèques JavaScript.
Cependant, s'il vous plaît, n'écrivez pas le code comme ça. De telles astuces ne rendent certainement pas le code plus clair ou plus lisible.
Une autre fonctionnalité intéressante est la possibilité d’enchaîner les missions :
soit a, b, c ; une = b = c = 2 + 2 ; alerte( une ); // 4 alerte( b ); // 4 alerte( c ); // 4
Les affectations enchaînées sont évaluées de droite à gauche. Tout d’abord, l’expression la plus à droite 2 + 2
est évaluée puis affectée aux variables de gauche : c
, b
et a
. Au final, toutes les variables partagent une seule valeur.
Encore une fois, pour des raisons de lisibilité, il est préférable de diviser ce code en quelques lignes :
c = 2 + 2 ; b = c; une = c;
C'est plus facile à lire, surtout lors d'une analyse oculaire rapide du code.
Nous devons souvent appliquer un opérateur à une variable et stocker le nouveau résultat dans cette même variable.
Par exemple:
soit n = 2 ; n = n + 5 ; n = n * 2 ;
Cette notation peut être raccourcie à l'aide des opérateurs +=
et *=
:
soit n = 2 ; m+= 5 ; // maintenant n = 7 (identique à n = n + 5) m*= 2 ; // maintenant n = 14 (identique à n = n * 2) alerte( n ); // 14
De courts opérateurs « modifier et attribuer » existent pour tous les opérateurs arithmétiques et au niveau du bit : /=
, -=
, etc.
De tels opérateurs ont la même priorité qu'une affectation normale, ils s'exécutent donc après la plupart des autres calculs :
soit n = 2 ; n*= 3 + 5 ; // partie droite évaluée en premier, identique à n *= 8 alerte( n ); // 16
Augmenter ou diminuer un nombre de un fait partie des opérations numériques les plus courantes.
Il existe donc des opérateurs spéciaux pour cela :
Incrément ++
augmente une variable de 1 :
soit compteur = 2 ; compteur++; // fonctionne de la même manière que counter = counter + 1, mais est plus court alerte( compteur ); // 3
Décrémenter --
diminue une variable de 1 :
soit compteur = 2 ; comptoir--; // fonctionne de la même manière que counter = counter - 1, mais est plus court alerte( compteur ); // 1
Important:
L'incrément/décrément ne peut être appliqué qu'aux variables. Essayer de l'utiliser sur une valeur comme 5++
donnera une erreur.
Les opérateurs ++
et --
peuvent être placés avant ou après une variable.
Lorsque l'opérateur recherche la variable, elle est sous « forme suffixe » : counter++
.
La « forme préfixe » est lorsque l'opérateur passe avant la variable : ++counter
.
Ces deux instructions font la même chose : augmenter counter
de 1
.
Y a-t-il une différence ? Oui, mais nous ne pouvons le voir que si nous utilisons la valeur renvoyée de ++/--
.
Clarifions. Comme nous le savons, tous les opérateurs renvoient une valeur. L'incrémentation/décrémentation ne fait pas exception. La forme préfixe renvoie la nouvelle valeur tandis que la forme suffixe renvoie l'ancienne valeur (avant l'incrémentation/décrémentation).
Pour voir la différence, voici un exemple :
soit compteur = 1 ; soit a = ++compteur ; // (*) alerte(a); // 2
Dans la ligne (*)
, le préfixe ++counter
incrémente counter
et renvoie la nouvelle valeur, 2
. Ainsi, l' alert
affiche 2
.
Maintenant, utilisons le formulaire postfix :
soit compteur = 1 ; soit a = compteur++; // (*) a changé ++counter en counter++ alerte(a); // 1
Dans la ligne (*)
, la forme suffixe counter++
incrémente également counter
mais renvoie l' ancienne valeur (avant l'incrémentation). Ainsi, l' alert
affiche 1
.
Pour résumer :
Si le résultat de l’incrémentation/décrémentation n’est pas utilisé, il n’y a aucune différence quant à la forme à utiliser :
soit compteur = 0 ; compteur++; ++compteur ; alerte( compteur ); // 2, les lignes ci-dessus ont fait la même chose
Si nous souhaitons augmenter une valeur et utiliser immédiatement le résultat de l'opérateur, nous avons besoin de la forme du préfixe :
soit compteur = 0 ; alerte( ++compteur ); // 1
Si nous souhaitons incrémenter une valeur mais utiliser sa valeur précédente, nous avons besoin du formulaire suffixe :
soit compteur = 0 ; alerte( compteur++ ); // 0
Incrémenter/décrémenter parmi les autres opérateurs
Les opérateurs ++/--
peuvent également être utilisés dans des expressions. Leur priorité est supérieure à la plupart des autres opérations arithmétiques.
Par exemple:
soit compteur = 1 ; alerte( 2 * ++compteur ); // 4
Comparez avec :
soit compteur = 1 ; alerte( 2 * compteur++ ); // 2, car counter++ renvoie "l'ancienne" valeur
Bien que techniquement correcte, une telle notation rend généralement le code moins lisible. Une ligne fait plusieurs choses – ce n’est pas bon.
Lors de la lecture du code, un balayage oculaire « vertical » rapide peut facilement manquer quelque chose comme counter++
et il ne sera pas évident que la variable a augmenté.
Nous conseillons un style « une ligne – une action » :
soit compteur = 1 ; alerte( 2 * compteur ); compteur++;
Les opérateurs au niveau du bit traitent les arguments comme des nombres entiers de 32 bits et travaillent au niveau de leur représentation binaire.
Ces opérateurs ne sont pas spécifiques à JavaScript. Ils sont pris en charge dans la plupart des langages de programmation.
La liste des opérateurs :
ET ( &
)
OU ( |
)
XOR ( ^
)
PAS ( ~
)
MAJ GAUCHE ( <<
)
MAJ DROITE ( >>
)
DÉCALAGE À DROITE DE REMPLISSAGE À ZÉRO ( >>>
)
Ces opérateurs sont utilisés très rarement, lorsque nous devons manipuler des nombres au niveau le plus bas (au niveau du bit). Nous n'aurons pas besoin de ces opérateurs de sitôt, car le développement Web les utilise peu, mais dans certains domaines particuliers, comme la cryptographie, ils sont utiles. Vous pouvez lire le chapitre Bitwise Operators sur MDN en cas de besoin.
L' ,
virgule est l'un des opérateurs les plus rares et les plus inhabituels. Parfois, il est utilisé pour écrire du code plus court, nous avons donc besoin de le connaître pour comprendre ce qui se passe.
L'opérateur virgule nous permet d'évaluer plusieurs expressions en les divisant par une virgule ,
. Chacun d'eux est évalué mais seul le résultat du dernier est renvoyé.
Par exemple:
soit a = (1 + 2, 3 + 4) ; alerte( une ); // 7 (le résultat de 3 + 4)
Ici, la première expression 1 + 2
est évaluée et son résultat est rejeté. Ensuite, 3 + 4
est évalué et renvoyé comme résultat.
La virgule a une très faible priorité
Veuillez noter que l'opérateur virgule a une très faible priorité, inférieure à =
, les parenthèses sont donc importantes dans l'exemple ci-dessus.
Sans eux : a = 1 + 2, 3 + 4
évalue +
d'abord, en additionnant les nombres dans a = 3, 7
, puis l'opérateur d'affectation =
attribue a = 3
et le reste est ignoré. C'est comme (a = 1 + 2), 3 + 4
.
Pourquoi avons-nous besoin d’un opérateur qui supprime tout sauf la dernière expression ?
Parfois, les gens l’utilisent dans des constructions plus complexes pour regrouper plusieurs actions sur une seule ligne.
Par exemple:
// trois opérations sur une ligne pour (a = 1, b = 3, c = a * b; a < 10; a++) { ... }
De telles astuces sont utilisées dans de nombreux frameworks JavaScript. C'est pourquoi nous les mentionnons. Mais généralement, ils n’améliorent pas la lisibilité du code, nous devons donc bien réfléchir avant de les utiliser.
importance : 5
Quelles sont les valeurs finales de toutes les variables a
, b
, c
et d
après le code ci-dessous ?
soit a = 1, b = 1 ; soit c = ++a; // ? soit d = b++ ; // ?
La réponse est :
a = 2
b = 2
c = 2
d = 1
soit a = 1, b = 1 ; alerte( ++a ); // 2, le formulaire préfixe renvoie la nouvelle valeur alerte( b++ ); // 1, le formulaire postfix renvoie l'ancienne valeur alerte( une ); // 2, incrémenté une fois alerte( b ); // 2, incrémenté une fois
importance : 3
Quelles sont les valeurs de a
et x
après le code ci-dessous ?
soit a = 2 ; soit x = 1 + (a *= 2) ;
La réponse est :
a = 4
(multiplié par 2)
x = 5
(calculé comme 1 + 4)
importance : 5
Quels sont les résultats de ces expressions ?
"" + 1 + 0 "" - 1 + 0 vrai + faux 6 / "3" "2" * "3" 4 + 5 + "px" "$" + 4 + 5 "4" - 2 "4px" - 2 " -9 " + 5 " -9 " - 5 nul + 1 indéfini + 1 " t n" - 2
Réfléchissez bien, écrivez puis comparez avec la réponse.
"" + 1 + 0 = "10" // (1) "" - 1 + 0 = -1 // (2) vrai + faux = 1 6 / "3" = 2 "2" * "3" = 6 4 + 5 + "px" = "9px" "$" + 4 + 5 = "45$" "4" - 2 = 2 "4px" - 2 = NaN " -9 " + 5 = " -9 5" // (3) " -9 " - 5 = -14 // (4) nul + 1 = 1 // (5) non défini + 1 = NaN // (6) " t n" - 2 = -2 // (7)
L'ajout avec une chaîne "" + 1
convertit 1
en chaîne : "" + 1 = "1"
, et on a alors "1" + 0
, la même règle est appliquée.
La soustraction -
(comme la plupart des opérations mathématiques) ne fonctionne qu'avec des nombres, elle convertit une chaîne vide ""
en 0
.
L'ajout avec une chaîne ajoute le chiffre 5
à la chaîne.
La soustraction est toujours convertie en nombres, elle fait donc de " -9 "
un nombre -9
(en ignorant les espaces qui l'entourent).
null
devient 0
après la conversion numérique.
undefined
devient NaN
après la conversion numérique.
Les espaces sont supprimés du début et de la fin de la chaîne lorsqu'une chaîne est convertie en nombre. Ici, la chaîne entière est constituée de caractères d'espacement, tels que t
, n
et d'un espace « normal » entre eux. Ainsi, comme pour une chaîne vide, elle devient 0
.
importance : 5
Voici un code qui demande à l'utilisateur deux nombres et affiche leur somme.
Cela ne fonctionne pas correctement. La sortie dans l'exemple ci-dessous est 12
(pour les valeurs d'invite par défaut).
Pourquoi? Réparez-le. Le résultat devrait être 3
.
let a = prompt("Premier numéro ?", 1); let b = prompt("Deuxième numéro ?", 2); alerte (a + b); // 12
La raison en est que l'invite renvoie l'entrée de l'utilisateur sous forme de chaîne.
Les variables ont donc respectivement les valeurs "1"
et "2"
.
soit a = "1" ; // prompt("Premier numéro ?", 1); soit b = "2" ; // prompt("Deuxième numéro ?", 2); alerte (a + b); // 12
Ce que nous devrions faire est de convertir les chaînes en nombres avant +
. Par exemple, en utilisant Number()
ou en les préfixant de +
.
Par exemple, juste avant prompt
:
let a = +prompt("Premier numéro ?", 1); let b = +prompt("Deuxième numéro ?", 2); alerte (a + b); // 3
Ou dans l' alert
:
let a = prompt("Premier numéro ?", 1); let b = prompt("Deuxième numéro ?", 2); alerte(+a + +b); // 3
Utilisation à la fois unaire et binaire +
dans le dernier code. Ça a l'air drôle, n'est-ce pas ?