# Programmation JavaScript/Opérateurs

* Introduction
    Programmer en deux minutes
*   * Page wiki
*   * Compteur en temps réel
*   * Site dans un document
* Outils de développement
* Syntaxe
** Ligne d'instruction
** Ordre d'évaluation
** Bloc d'instructions
** Identificateurs
** Expression littérale
** Commentaire
** Mots réservés
** Variables
** Opérateurs
** Structures de contrôle
** Exceptions et erreurs
** Fonctions utilisateur
** Évènement
* Objets prédéfinis
** window
** document
** navigator
** Array
** Boolean
** Date
** Error
** Function
** Math
** Number
** Object
** String
** Element
** RegExp
* Fonctions prédéfinies
* Programmation avancée
** Opérateurs de bits
** Fermeture
** Programmation objet
** Notation JSON
** AJAX
** Stockage
** Générateurs
** Interface DOM
** Objets Microsoft
* Frameworks
** Dojo
    Hello World
    Widgets
    Ressources
** jQuery
** Node.js
** React.js
* Tests
** Ava
** Jest
** Cypress
* Débogage
* Erreurs connues
* Références
* Introduction
    Programmer en deux minutes
*   * Page wiki
*   * Compteur en temps réel
*   * Site dans un document
* Outils de développement
* Syntaxe
** Ligne d'instruction
** Ordre d'évaluation
** Bloc d'instructions
** Identificateurs
** Expression littérale
** Commentaire
** Mots réservés
** Variables
** Opérateurs
** Structures de contrôle
** Exceptions et erreurs
** Fonctions utilisateur
** Évènement
* Objets prédéfinis
** window
** document
** navigator
** Array
** Boolean
** Date
** Error
** Function
** Math
** Number
** Object
** String
** Element
** RegExp
* Fonctions prédéfinies
* Programmation avancée
** Opérateurs de bits
** Fermeture
** Programmation objet
** Notation JSON
** AJAX
** Stockage
** Générateurs
** Interface DOM
** Objets Microsoft
* Frameworks
** Dojo
    Hello World
    Widgets
    Ressources
** jQuery
** Node.js
** React.js
* Tests
** Ava
** Jest
** Cypress
* Débogage
* Erreurs connues
* Références
[ Modifier le sommaire ]
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 true ou false, 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 (window) 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 Math.PI) 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 <<<).
ma_var = ma_var + 2 est remplacé avantageusement par ma_var += 2 ma_var = ma_var / 2 peut s'écrire ma_var /= 2 ma_var = ma_var << 2 peut s'écrire ma_var <<= 2 ma_var = ma_var ^ 1 peut s'écrire ma_var ^= 1 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 null). 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 new Number, de l'objet null, ou de la valeur undefined, 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 :
* 3 + 1 donne 4
Dans le cas limite Infinity + -Infinity, 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 :
* 3 + "bonjour" donne "3bonjour" (et non 0)
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 Infinity-Infinity, 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 Infinity*0, 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 Infinity/Infinity et 0/0, 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 javascript:. 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 true 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 :
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 :

### 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 :

### 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 :

### 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 :

### 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 :
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 :
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 :
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é == renvoie la valeur vrai si les deux termes à comparer sont équivalents.
L'opérateur === compare les valeurs et leur type. Le résultat est vrai (true) si les deux valeurs sont égales et de même type.
Si les deux opérandes sont des références (types object, function...), c'est les références qui sont comparées.
Quelques valeurs spéciales :
* undefined est seulement équivalent, mais pas identique, à null.
* La chaîne vide "" est équivalente au nombre zéro, au booléen false, et à une liste vide.
* Tous les nombres sont équivalents à leurs représentations sous forme de chaîne.
* Le nombre 1 est, de plus, équivalent au booléen true.
* Par contre le nombre NaN n'est pas équivalent à la chaîne "NaN".
Ces équivalences sont commutatives.

### Inégalité (!=, !==)

L'opérateur d'inégalité != renvoie la valeur vrai si les deux termes à comparer sont différents.
L'opérateur !== compare les valeurs et leur type. Le résultat est vrai (true) si les deux valeurs sont différentes ou de type différent.

### Ordre (<, <=, >=, >)

Respectivement inférieur, inférieur ou égal, supérieur ou égal, supérieur, permet de comparer des valeurs.
À 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 new Number, 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 :
    En langage C cette instruction peut être utilisée car une chaîne de caractères en C est un pointeur, donc fondamentalement un nombre entier. Ce n'est pas le cas en JavaScript.
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 :
* Lorsque l'opérateur est placé à droite, l'opération retourne d'abord la valeur de départ de la variable puis l'incrémente (Post-incrémentation);
* Lorsque l'opérateur est à gauche, l'opération incrémente d'abord la variable puis retourne sa valeur modifiée (Pré-incrémentation).

## 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 :

### 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.
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 :
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 :
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 :
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é.
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 :
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).

### 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.
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 :
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".

### 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.
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 null, 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] var perso = {nom : "Potter", prenom : "Harry"}
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 hasOwnProperty(name) : <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 :