Programmation JavaScript/Opérateurs
Les opérateurs JavaScript reprennent la plupart des opérateurs du langage C.
Affectation (= et ses dérivés).
Le principal opérateur d'affectation est le signe égal (=). Il permet d'affecter une valeur à une variable.
Comme en C, l'opérateur d'affectation copie la valeur de l'expression qui le suit (opérande de droite) dans la variable qui le précède (opérande de gauche). Contrairement au C, l'opération d'affectation ne retourne généralement pas codice_1 ou codice_2, mais la valeur qui a été affectée. Dans le cas où l'affectation est impossible, JavaScript lance une exception.
Lorsque l'identifiant à gauche du signe = n'est pas une propriété existante, cette propriété est ajoutée automatiquement à l'objet global (codice_3) et l'affectation se déroule normalement. Il n'y a jamais d'erreur lorsqu'on affecte une valeur à une variable d'un type différent car ce sont les valeurs elles-mêmes qui ont un type en JavaScript, pas les variables. L'affectation à une constante prédéfinie (comme codice_4) ne provoque pas d'erreur mais la constante ne sera pas modifiée.
La seule cause d'erreur possible lors d'une affectation est lorsque l'opérande de gauche n'est pas une variable valide ou devient autre chose qu'une variable avant l'affectation :
JavaScript reprend les raccourcis sténographiques du langage C en proposant les autres opérateurs d'affectation qui font précéder le signe égal par un opérateur binaire arithmétique (+, -, *, / ou %), de concaténation (+), bit-à-bit (&, | ou ^) ou de décalage de bits («, » ou «<).
codice_5 est remplacé avantageusement par codice_6
codice_7 peut s'écrire codice_8
codice_9 peut s'écrire codice_10
codice_11 peut s'écrire codice_12
et ainsi de suite.
Concaténation (+).
Surchargé avec l'opérateur arithmétique d'addition, l'opérateur de concaténation permet de joindre des chaînes, ou des chaînes avec d'autres objets comme des nombres, qui sont alors automatiquement convertis en chaîne. Le résultat d'une concaténation est du type string.
La concaténation ne provoque jamais d'erreur car en JavaScript, absolument tout peut être converti en chaîne.
Attention, l'opérateur + fonctionne ainsi dès qu'au moins une des opérandes est de type "string" (y compris la chaîne vide ""), "function" ou "object" (à l'exception de codice_13). Une chaîne représentant un nombre, par exemple la chaîne "17", sera considérée comme une chaîne et ne sera pas convertie automatiquement en nombre par cet opérateur.
Opérateurs arithmétiques.
Addition (+).
En présence de deux opérandes de type number ou boolean, d'objets construits avec codice_14, de l'objet codice_13, ou de la valeur codice_16, l'opérateur d'addition va effectuer la somme arithmétique des deux valeurs, après les avoir converties en nombre le cas échéant. Le résultat de l'addition est de type number :
Exemple :
Dans le cas limite codice_19, le résultat est NaN.
Attention : si au moins l'un des deux objets ne fait pas partie de ceux mentionnés ci-dessus, alors l'opérateur se comporte comme un opérateur de concaténation : 
Exemple : 
Accessoirement, l'opérateur + avec une seule opérande à sa droite se comporte comme un opérateur unaire de conversion en nombre, comme la méthode Number(). C'est très utile pour forcer justement les autres + à additionner au lieu de concaténer :
Soustraction (-).
Retourne la différence arithmétique entre deux valeurs de type number ou converties dans ce type.
Le résultat est lui-même de type number.
Comme pour tous les opérateurs arithmétiques, si l'une des deux opérandes, (ou les deux) n'est pas un nombre (NaN, soit à l'origine, soit parce que la conversion en nombre n'a pas été possible), l'opérateur renvoie NaN (Not a Number). Dans le cas limite codice_22, le résultat est également NaN.
Accessoirement, le signe - avec une seule opérande à sa droite devient un opérateur unaire qui en change le signe (après l'avoir convertie en nombre si nécessaire).
Multiplication (*).
Retourne le produit arithmétique de deux valeurs de type number ou converties dans ce type.
Le résultat est lui-même de type number.
Comme pour tous les opérateurs arithmétiques, si l'une des deux opérandes, (ou les deux) n'est pas un nombre (NaN, soit à l'origine, soit parce que la conversion en nombre n'a pas été possible), l'opérateur renvoie NaN (Not a Number).
Dans le cas limite codice_23, le résultat est également NaN.
Division (/).
L'opérateur de division permet d'effectuer la division de deux entités de type number ou converties dans ce type.
Le résultat est lui-même de type number.
Comme pour tous les opérateurs arithmétiques, si l'une des deux opérandes, (ou les deux) n'est pas un nombre (NaN, soit à l'origine, soit parce que la conversion en nombre n'a pas été possible), l'opérateur renvoie NaN (Not a Number). Dans les cas limite codice_24 et codice_25, le résultat est également NaN.
À noter : la division d'un autre nombre par zéro est possible et retourne le nombre Infinity sans provoquer d'erreur.
Attention : le signe / est également utilisé pour délimiter les expressions rationnelles. En cas d'ambiguïté (même en cas de saut de ligne sans point-virgule), JavaScript privilégie la division.
Modulo (%).
L'opérateur '%' permet d'effectuer l'opération mathématique "modulo"
Il retourne l'opérande de gauche modulo l'opérande de droite, et les deux opérandes sont d'abord converties en number si elles étaient d'un autre type.
Le résultat est lui-même de type number.
Comme pour tous les opérateurs arithmétiques, si l'une des deux opérandes, (ou les deux) n'est pas un nombre (NaN, soit à l'origine, soit parce que la conversion en nombre n'a pas été possible), l'opérateur renvoie NaN (Not a Number). De plus, n'importe quel nombre modulo zéro retournera NaN.
À noter : l'opérateur % accepte sans problème des nombres non-entiers pour les deux opérandes mais dans ce cas il y a souvent un problème de précision, par exemple 4%1.6 affichera 0.7999999999999998 au lieu de 0.8.
Attention : le signe % est utilisé par l'encodage des URL. S'il est suivi de deux chiffres hexadécimaux, le navigateur convertira la séquence %xx en un caractère si le code se trouve dans une URL codice_26. Pour éviter ce problème, mettez l'opérande de droite entre parenthèses ou bien séparez-la de l'opérateur par un espace.
Limitation sur les entiers.
Javascript n'a pas de type pour les nombres entiers, il utilise des nombres à virgule flottante.
Les entiers ou les chiffres d'un nombre réel sont limités à 54 bits dans les opérations arithmétiques, et à 32 bits dans les opérations sur les bits.
Par exemple, l'expression 0xF0000000000003FF == 0xF000000000000000 retourne codice_1 car seuls les 54 bits de poids forts sont stockés.
Opérateurs logiques.
ET (&&).
L'opérateur logique &&, aussi appelé "prérequis", détermine si deux expressions sont "vraies" (au sens booléen). Le résultat est l'une des deux opérandes, et la conversion booléenne du résultat est identique au résultat de l'opérateur && dans les langages où il retourne simplement un booléen.
Cet opérateur est utilisé fréquemment dans les structures de contrôle if, while, etc :
L'opérateur && en JavaScript retourne l'opérande de gauche si elle est fausse (c'est-à-dire si sa conversion en booléen est égale à false) "sans évaluer l'expression de droite", et sinon, évalue et retourne l'opérande de droite.
Par conséquent, son résultat n'est généralement "pas un booléen" et && n'est pas strictement commutatif :
Cela peut provoquer quelques comportements inattendus, par exemple :
Mais on peut aussi en tirer partie pour condenser un code tel que celui-ci :
en le remplaçant par celui-ci :
D'où le nom "prérequis" : l'opérande de droite "requiert" que l'opérande de gauche soit vraie pour être évaluée et retournée.
OU (||).
L'opérateur logique ||, aussi appelé "défaut", détermine si au moins une expression est "vraie" (au sens booléen). Le résultat est l'une des deux opérandes, et la conversion booléenne du résultat est identique au résultat de l'opérateur || dans les langages où il retourne simplement un booléen.
L'opérateur || en JavaScript retourne l'opérande de gauche si elle est vraie (c'est-à-dire si sa conversion en booléen est égale à true) "sans évaluer l'expression de droite", et sinon, évalue et retourne l'opérande de droite.
Par conséquent, son résultat n'est généralement "pas un booléen" et || n'est pas strictement commutatif :
Cela peut provoquer quelques comportements inattendus, par exemple :
Mais on peut aussi en tirer partie pour condenser un code tel que celui-ci :
en le remplaçant par celui-ci :
D'où le nom "défaut" : si l'opérande de gauche a une valeur non-nulle, elle est utilisée, mais sinon l'opérande de droite est utilisée comme valeur "par défaut". Cela permet à la fonction dans ce dernier exemple de prévoir une valeur par défaut pour son argument 'n', au cas où il ne serait pas fourni.
NON (!).
L'opérateur de négation ! contredit logiquement l'expression qu'il précède. Il en convertit d'abord la valeur en booléen si elle était d'un autre type, et retourne le booléen contraire.
Si on l'utilise deux fois de suite (!!) il permet simplement de convertir la valeur de son opérande en booléen :
mais
Opérateurs de bits.
Les opérateurs bit-à-bit et de décalage de bits commencent par convertir leurs opérandes en entiers de 32bits, après les avoir converties en number si c'était nécessaire. Les nombres NaN et Infinity donnent le nombre entier "zéro".
Les opérateurs logiques &, |, ^ et ~ effectuent un test logique séparément sur chaque bit, de la manière illustrée par l'exemple suivant ou l'opérateur est un ET bit-à-bit :
var n = 26 & 12 ;
 1 1 0 1 0 (26 en binaire)
 0 1 1 0 0 (12 en binaire)
 1&0 1&1 0&1 1&0 0&0 <- opérations bit à bit
 0 1 0 0 0 <- résultat (8 en binaire)
Les autres opérateurs de bits sont les opérateurs de décalage des bits (vers la droite ou la gauche).
Et binaire (&).
Cet opérateur retourne pour deux opérandes entiers (a et b) un nombre entier c dont chaque bit est calculé par la table de vérité suivante :
 a & b = c
 0 0 0
 0 1 0
 1 0 0
 1 1 1
Ou binaire (|).
Cet opérateur retourne pour deux opérandes entiers (a et b) un nombre entier c dont chaque bit est calculé par la table de vérité suivante :
 a | b = c
 0 0 0
 0 1 1
 1 0 1
 1 1 1
Ou exclusif binaire (^).
Cet opérateur retourne pour deux opérandes entiers (a et b) un nombre entier c dont chaque bit est calculé par la table de vérité suivante :
 a ^ b = c
 0 0 0
 0 1 1
 1 0 1
 1 1 0
Non binaire (~).
Cet opérateur retourne pour un opérande entier a un nombre entier c dont chaque bit est l'opposé du bit original :
 ~a = c
 0 1
 1 0
Décalage de bits vers la gauche («).
Cet opérateur retourne l'opérande de gauche après avoir décalé ses bits vers la gauche du nombre de bits spécifié par l'opérande de droite, en ajoutant de nouveaux bits de valeur nulle et en supprimant les bits qui dépassent de l'autre côté.
Exemple :
var c = 15 « 3;
 0 0 0 0 1 1 1 1 (15 en binaire)
 0 1 1 1 1 0 0 0 (décalé de 3 bits vers la gauche en ajoutant des zéros)
Attention : le bit le plus à gauche détermine le signe du nombre, et il est aussi affecté par le décalage.
Décalage de bits vers la droite (»).
Cet opérateur retourne l'opérande de gauche après avoir décalé ses bits vers la droite du nombre de bits spécifié par l'opérande de droite, en ajoutant de nouveaux bits de valeur nulle à droite et en supprimant des bits de poids faible (les plus à gauche dans la représentation binaire).
Exemple :
var c = 15 » 3;
 0 0 0 0 1 1 1 1 (15 en binaire)
 0 0 0 0 0 0 0 1 (décalé de 3 bits vers la droite en supprimant les bits 1 1 1)
Le bit de signe (le plus à gauche) est préservé.
Décalage de bits vers la droite y compris le bit de signe (»>).
Cet opérateur retourne l'opérande de gauche après avoir décalé ses bits vers la droite du nombre de bits spécifié par l'opérande de droite, en ajoutant de nouveaux bits de valeur nulle à droite et en supprimant des bits de poids faible (les plus à gauche dans la représentation binaire).
Exemple :
var c = -15 »> 3;
Attention : le bit le plus à gauche détermine le signe du nombre, et il est aussi affecté par le décalage. Le résultat de l'exemple ci-dessus est 536870910.
Opérateurs de comparaison.
Égalité (==,.
L'opérateur d'égalité codice_28 renvoie la valeur vrai si les deux termes à comparer sont équivalents.
valeur="50";
if (valeur == 50) alert("valeur vaut 50");
// l'alerte sera affichée
L'opérateur codice_29 compare les valeurs et leur type. Le résultat est vrai (codice_1) si les deux valeurs sont égales et de même type.
valeur="50";
if (valeur === 50) alert("valeur vaut 50 (nombre entier)");
// l'alerte ne sera pas affichée (chaîne et entier sont deux types différents)
Si les deux opérandes sont des références (types object, function...), c'est les références qui sont comparées.
if ([] == []) alert("les deux listes sont identiques");
// l'alerte ne sera pas affichée (chaque opérande est une référence différente même si les listes [] et [] sont semblables)
Quelques valeurs spéciales :
Ces équivalences sont commutatives.
Inégalité (!=, !==).
L'opérateur d'inégalité codice_31 renvoie la valeur vrai si les deux termes à comparer sont différents.
valeur="50";
if (valeur != 50) alert("valeur ne vaut pas 50");
// l'alerte ne sera pas affichée
L'opérateur codice_32 compare les valeurs et leur type. Le résultat est vrai (codice_1) si les deux valeurs sont différentes ou de type différent.
valeur="50";
if (valeur !== 50) alert("valeur ne vaut pas 50 (nombre entier)");
// l'alerte sera affichée (chaîne et entier sont deux types différents)
Ordre (<, <=, >=, >).
Respectivement inférieur, inférieur ou égal, supérieur ou égal, supérieur, permet de comparer des valeurs.
if (10 > 5) alert("Normal, c'est le double");
À l'instar de l'opérateur +, les opérateurs de comparaison peuvent comparer numériquement ou alphabétiquement. Si les deux opérandes sont de types number ou boolean, object construit par codice_14, ou les valeurs null ou undefined (les mêmes valeurs qui font que l'opérateur + les additionnerait), alors les valeurs sont converties en nombres et comparées en tant que telles.
Sinon, les valeurs sont converties en chaînes et comparées alphabétiquement.
Opérateurs d'incrémentation et décrémentation (++ --).
Ces deux opérateurs proposent un moyen simple d'incrémenter ou décrémenter une variable de type number. Si l'opérande n'est pas de type number, elle est convertie automatiquement. Si ce n'est pas une variable du tout, cela provoque une erreur comme pour l'affectation.
Note : Appliqué sur une valeur qui ne peut être convertie, comme une chaîne qui ne représente pas un nombre, l'opérateur abîme définitivement le contenu de la variable. Contrairement à l'opérateur +, l'opérateur ++ ne concatène jamais.
Remarque :
Comme dans les autres langages, les opérateurs ++ et -- peuvent être placés avant ou après leur opérande. Cela change la valeur retournée par l'opération :
Opérateurs spéciaux.
Conditionnel (? :).
L'opérateur conditionnel est ternaire (il prend trois opérandes). Il est représenté par le signe ? qui sépare les deux premières, et : qui sépare les deux dernières. L'opération retourne l'une des deux opérandes qui entourent les deux points (:) après avoir déterminé si l'expression précédant le point d'interrogation (?) est vraie ou fausse.
Si X est vrai (autrement dit si sa conversion en booléen donne true), l'opération évalue et retourne A sans évaluer B. Sinon, elle évalue et retourne B sans évaluer A.
On peut se représenter l'opérateur avec une structure if...else classique :
if(X)
 resultat = A
else
 resultat = B
Instanciation (new).
L'opérateur new crée un nouvel objet qui hérite du prototype de la fonction qui le suit, puis appelle cette fonction dans laquelle le mot-clé "this" sera une référence à ce nouvel objet. La fonction qui sert d'opérande à new (le "constructeur") peut prendre des arguments. Le résultat de l'opération est l'objet ainsi créé, sauf si le constructeur retourne autre chose.
maintenant = new Date() // crée un objet avec la fonction prédéfinie Date
function Livre( nom, auteur ) // définition d'un constructeur
 this.nom = nom
 this.auteur = auteur || "personne" // définit une valeur par défaut si auteur est undefined, null, false, 0 ou "
hp = new Livre( "Harry Potter et les Reliques de la Mort", "JK Rowling" )
Il est possible, dans l'opération d'instanciation, d'omettre les parenthèses après le nom de la fonction (comme si on ne l'appelait pas) lorsqu'on ne lui passe aucun argument :
maintenant = new Date // crée un objet avec la fonction prédéfinie Date
Bien sûr, une référence du constructeur est suffisante pour instancier un objet, il n'est pas nécessaire d'utiliser le nom de la fonction tel que défini dans la déclaration function :
o = Date
maintenant = new o() // crée un objet avec la fonction prédéfinie Date
Il est même possible de déclarer le constructeur dans la même ligne que new, et même d'utiliser une fonction anonyme :
singleton = new ( function (){ this.prop = "valeur" } )() 
Si l'opérande n'est pas de type "function", l'opération provoque une erreur.
Dé-référencement (delete).
L'opérateur delete supprime la propriété qui le suit. Si la propriété contient une référence à un objet, seule la référence est supprimée : l'objet existe toujours et, s'il est référencé par d'autres variables, ne sera pas supprimé.
a = 3
b = ["une", "liste"]
delete a // a n'existe plus, ni sa valeur
delete b // supprime la propriété b ; la liste elle-même sera libérée car elle n'a plus aucune référence
delete c.prop
alert("prop" in c) // affiche false
Note : seul l'opérateur delete efface la propriété. Affecter null ou undefined à une variable déréférence l'objet qu'elle référençait s'il y en avait un, mais la variable existe toujours :
a = new Date()
a = undefined
alert(a) // affiche "undefined"
delete a
alert(a) // erreur !
c.prop = undefined
alert("prop" in c) // affiche true
delete c.prop
alert("prop" in c) // affiche false
delete peut supprimer toute propriété existante (y compris prédéfinies telles que Math, Object...), mais pas les variables locales déclarées avec var ni les arguments d'une fonction, ni les variables NaN et undefined. Dans les cas où la variable ne peut pas être supprimée, l'opération retourne false. delete accepte aussi des propriétés inexistantes, et des valeurs anonymes (dans ce cas, il n'a aucun effet).
a = "valeur"
var b = "valeur"
delete a // true
delete b // false, et b n'est pas détruit
delete 17 // true, totalement inutile, et on peut toujours utiliser le nombre 17
delete Math.PI // false, c'est une propriété en lecture seule
delete Math // true, et c'est dommage parce qu'on ne peut plus accéder à l'objet Math !
Propriété d'un objet (.).
L'opérateur . (point) permet simplement d'accéder à la propriété, nommée par l'opérande de droite, de l'objet référencé par l'opérande de gauche. L'opérande de droite doit être un identifiant ; l'opérande de gauche peut être n'importe quelle expression qui retourne un objet différent de null.
window . document . URL // affiche la propriété "URL" de l'objet référencé par la propriété "document" de l'objet window
Math . sin( 1.5 ) // appelle la méthode référencée par la propriété "sin" de l'objet Math
new Date() . getTime() // appelle la méthode référencée par la propriété "getTime" d'un objet construit par Date
Si l'opérande de gauche est une valeur scalaire (string, boolean ou number), elle est convertie en un objet correspondant. Par exemple, une chaîne est convertie en un objet construit par String :
"chaîne".charAt(2) // affiche "a"
L'opérande de droite n'a pas besoin de désigner une propriété existante de l'objet. Il suffit (et il faut) que ce soit un identifiant valide.
L'opération provoque une erreur si l'opérande de gauche est undefined ou null, ou si l'opérande de droite n'est pas un identifiant.
Attention, le point est également le séparateur entre parties entière et décimale d'un nombre. S'il est immédiatement précédé par un nombre entier (sans espace), il ne fonctionnera pas comme opérateur.
Propriété d'un objet existant (?.).
Idem sur "." mais sans erreur ("TypeError") si l'objet n'existe pas.
Valeur d'une variable inexistante (??).
Définit une valeur par défaut si une variable est null ou undefined.
Type de variable (typeof).
L'opérateur typeof retourne une chaîne représentant le type de la valeur de l'expression à sa droite. Les possibilités sont "undefined", "boolean", "number", "string", "object" et "function".
if((typeof arg) != "number")
 alert("arg n'est pas un nombre !")
Type d'objet (instanceof).
L'opérateur instanceof détermine si l'opérande de gauche "hérite" de l'objet à droite. C'est-à-dire, pour parler JavaScript, si le prototype de l'objet à droite de instanceof se trouve dans la chaîne de prototypes de l'opérande de gauche. instanceof retourne un booléen.
L'opérande de droite n'a pas besoin d'être le constructeur de celle de gauche pour que instanceof retourne true.
new Date() instanceof Date // true
new Date() instanceof Object // true
new Date() instanceof Array // false
[2,7,8] instanceof Array // true
instanceof retourne toujours false lorsque l'opérande de gauche est une valeur scalaire (types string, boolean, number), undefined ou null. Une erreur se produit si c'est l'opérande de droite qui est dans ce cas.
Appartenance à une liste (in).
L'opérateur in détermine si l'expression à sa gauche est le nom d'une propriété de l'objet à sa droite. L'opérande de droite doit obligatoirement être de type "object" et différente de codice_13, sinon l'opération provoque une erreur. L'opérande de gauche peut être n'importe quelle valeur car elle sera automatiquement convertie en chaîne.
Exemple :
<syntaxhighlight lang="javascript">var liste = [1, 5, "bleu", new Date()]
alert(2 in liste) // affiche true car liste[2] existe
alert("bleu" in liste) // affiche false car "bleu" est la valeur de liste[2] mais pas une clé de la liste
alert("length" in liste) // affiche true car liste est un Array qui possède une propriété length
alert("nom" in perso) // affiche true, l'objet perso possède bien une propriété "nom"
alert("Harry" in perso) // affiche false, "Harry" n'est pas une propriété mais la valeur d'une propriété
alert("toString" in perso) // affiche true, l'objet perso hérite la méthode toString du prototype de Object
</source >
On voit que in va chercher dans le prototype des objets s'il ne trouve pas la propriété dans l'objet lui-même. Pour savoir si une propriété est directement possédée par un objet, il y a la méthode codice_36 :
<syntaxhighlight lang="javascript">alert(perso.hasOwnProperty("nom")) // true
alert(perso.hasOwnProperty("toString")) // false
</source >
Dans le contexte de la structure de contrôle for... in, l'opérateur in joue un rôle un peu différent.
Juxtaposition (,).
L'opérateur "virgule" permet simplement de juxtaposer plusieurs expressions, et retourne la valeur de la dernière (celle de droite).
Ce code va afficher le nombre 1, mais l'affectation x=3 aura bien lieu d'abord.
C'est très utilisé dans les boucles for, où on doit parfois initialiser, tester ou incrémenter plusieurs variables différentes en une seule expression.
Le signe "virgule" fonctionne différemment dans certains contextes (notamment quand on énumère les éléments d'une liste ou d'un objet, ou les arguments d'une fonction, ce n'est plus qu'un simple séparateur).
affichera 3, parce que 3 et 1 seront considérés comme deux arguments de la méthode "alert" mais elle n'affiche que le premier.
Opérateur variadique (...).
Récupère tous les paramètres de l'appel d'une fonction dans un seul argument de sa signature.
Opérateur de déclaration privée (#).
Par défaut les attributs de classe sont publics. Pour les rendre privés, il faut les déclarer avec cet opérateur. Ex :