
La syntaxe de JavaScript est l'ensemble des règles qui définissent un programme JavaScript correctement structuré.
Les exemples ci-dessous utilisent la fonction log de l'objet console présent dans la plupart des navigateurs pour la sortie de texte standard .
La bibliothèque standard JavaScript ne dispose pas d'une fonction de sortie de texte standard officielle (à l'exception de document.write). Étant donné que JavaScript est principalement utilisé pour les scripts côté client dans les navigateurs Web modernes et que presque tous les navigateurs Web fournissent la fonction d'alerte, alertpeut également être utilisé, mais n'est pas couramment utilisé.
Origines
Brendan Eich a résumé l'ascendance de la syntaxe dans le premier paragraphe de la spécification JavaScript 1.1 comme suit :
JavaScript emprunte la plupart de sa syntaxe à Java , mais hérite également d' Awk et de Perl , avec une influence indirecte de Self dans son système de prototypes d'objets.
Notions de base
Sensibilité à la casse
JavaScript est sensible à la casse . Il est courant de commencer le nom d'un constructeur par une majuscule et le nom d'une fonction ou d'une variable par une minuscule.
Exemple:
var a = 5 ; console . log ( a ); // 5 console . log ( A ); // génère une ReferenceError : A n'est pas défini
Espaces et points-virgules
Contrairement à C , les espaces dans la source JavaScript peuvent avoir un impact direct sur la sémantique . Les points-virgules terminent les instructions en JavaScript. En raison de l'insertion automatique de points-virgules (ASI), certaines instructions bien formées lors de l'analyse d'un saut de ligne seront considérées comme complètes, comme si un point-virgule était inséré juste avant le saut de ligne. Certaines autorités conseillent de fournir explicitement des points-virgules de fin d'instruction, car cela peut réduire les effets indésirables de l'insertion automatique de points-virgules.
Il y a deux problèmes : cinq jetons peuvent soit commencer une instruction, soit être l'extension d'une instruction complète ; et cinq productions restreintes, où les sauts de ligne ne sont pas autorisés dans certaines positions, ce qui peut potentiellement entraîner une analyse incorrecte.
Les cinq tokens problématiques sont la parenthèse ouvrante " (", le crochet ouvrant " [", la barre oblique " /", le plus " +" et le moins " -". Parmi ceux-ci, la parenthèse ouvrante est courante dans le modèle d'expression de fonction immédiatement invoquée , et le crochet ouvrant se produit parfois, tandis que d'autres sont assez rares. Un exemple :
a = b + c ( d + e ). foo () // Traité comme : // a = b + c(d + e).foo();
avec la suggestion que la déclaration précédente soit terminée par un point-virgule.
Certains suggèrent plutôt l'utilisation de points-virgules de début sur les lignes commençant par ' (' ou ' [', afin que la ligne ne soit pas jointe accidentellement à la précédente. C'est ce qu'on appelle un point-virgule défensif , et il est particulièrement recommandé, car sinon le code peut devenir ambigu lorsqu'il est réorganisé. Par exemple :
a = b + c ;( d + e ). foo () // Traité comme : // a = b + c; // (d + e).foo();
Les points-virgules initiaux sont également parfois utilisés au début des bibliothèques JavaScript, au cas où ils seraient ajoutés à une autre bibliothèque qui omet un point-virgule de fin, car cela peut entraîner une ambiguïté de l'instruction initiale.
Les cinq productions restreintes sont return, throw, break, continueet post-incrémentation/décrémentation. Dans tous les cas, l'insertion de points-virgules ne résout pas le problème, mais rend la syntaxe analysée claire, ce qui rend l'erreur plus facile à détecter. returnet throwprennent une valeur facultative, while breaket continueprennent une étiquette facultative. Dans tous les cas, le conseil est de conserver la valeur ou l'étiquette sur la même ligne que l'instruction. Cela apparaît le plus souvent dans l'instruction de retour, où l'on peut renvoyer un littéral d'objet volumineux, qui peut être placé accidentellement à partir d'une nouvelle ligne. Pour la post-incrémentation/décrémentation, il existe une ambiguïté potentielle avec la pré-incrémentation/décrémentation, et encore une fois, il est recommandé de simplement les conserver sur la même ligne.
retourner a + b ; // Renvoie undefined. Traité comme : // return ; // a + b ; // Doit être écrit comme : // return a + b ;
Commentaires
La syntaxe des commentaires est la même que dans C++ , Swift et de nombreux autres langages.
// un commentaire court sur une seule ligne /* ceci est un long commentaire de plusieurs lignes sur mon script. Espérons qu'un jour il sera génial. */ /* Commentaires /* ne peuvent pas être imbriqués */ Erreur de syntaxe * /
Variables
Les variables en JavaScript standard n'ont pas de type attaché, donc n'importe quelle valeur (chaque valeur a un type) peut être stockée dans n'importe quelle variable. À partir d' ES6 , la 6e version du langage, les variables pouvaient être déclarées avec varpour les variables de portée de fonction et letou constqui sont pour les variables de niveau bloc . Avant ES6, les variables ne pouvaient être déclarées qu'avec une varinstruction. Les valeurs attribuées aux variables déclarées avec constne peuvent pas être modifiées, mais leurs propriétés peuvent l'être. varne devrait plus être utilisé depuis letet constsont pris en charge par les navigateurs modernes. identifiant d'une variable doit commencer par une lettre, un trait de soulignement ( _) ou un signe dollar ( $), tandis que les caractères suivants peuvent également être des chiffres ( 0-9). JavaScript est sensible à la casse, donc les caractères majuscules "A" à "Z" sont différents des caractères minuscules "a" à "z".
À partir de JavaScript 1.5, les lettres ISO 8859-1 ou Unicode (ou \uXXXXles séquences d'échappement Unicode) peuvent être utilisées dans les identifiants. Dans certaines implémentations JavaScript, le signe @ peut être utilisé dans un identifiant, mais cela est contraire aux spécifications et n'est pas pris en charge dans les implémentations plus récentes.
Détermination et levage
Les variables déclarées avec varsont limitées lexicalement au niveau de la fonction , tandis que celles avec letou constont une portée au niveau du bloc . Étant donné que les déclarations sont traitées avant l'exécution de tout code, une variable peut être affectée à et utilisée avant d'être déclarée dans le code. C'est ce qu'on appellelevage , et cela équivaut à ce que les variables soientdéclarées en avanten haut de la fonction ou du bloc.
Avec les instructions var, letet const, seule la déclaration est hissée ; les affectations ne le sont pas. Ainsi, une instruction au milieu de la fonction est équivalente à une instruction de déclaration en haut de la fonction et à une instruction d'affectation à ce point au milieu de la fonction. Cela signifie que les valeurs ne sont pas accessibles avant d'être déclarées ; la référence directe n'est pas possible. Avec la valeur d'une variable est jusqu'à ce qu'elle soit initialisée. Les variables déclarées avec ou ne sont pas accessibles tant qu'elles n'ont pas été initialisées, donc référencer ces variables avant provoquera une erreur. varx=1varxx=1varundefinedletconst
Les déclarations de fonction, qui déclarent une variable et lui attribuent une fonction, sont similaires aux instructions de variable, mais en plus de hisser la déclaration, elles hissent également l'affectation – comme si l'instruction entière apparaissait en haut de la fonction qui la contient – et donc une référence en avant est également possible : l'emplacement d'une instruction de fonction dans une fonction englobante n'a aucune importance. Cela diffère d'une expression de fonction assignée à une variable dans une instruction var, letou const.
Ainsi, par exemple,
var func = function () { .. } // la déclaration est hissée uniquement function func () { .. } // la déclaration et l'affectation sont hissées
La portée du bloc peut être produite en enveloppant le bloc entier dans une fonction, puis en l'exécutant (c'est ce qu'on appelle le modèle d'expression de fonction immédiatement invoquée ) ou en déclarant la variable à l'aide du letmot-clé.
Déclaration et cession
Les variables déclarées en dehors d'une portée sont globales . Si une variable est déclarée dans une portée supérieure, elle est accessible par les portées enfants.
Lorsque JavaScript tente de résoudre un identifiant, il recherche dans la portée locale. Si cet identifiant n'est pas trouvé, il recherche dans la portée externe suivante, et ainsi de suite le long de la chaîne de portées jusqu'à ce qu'il atteigne la portée globale où résident les variables globales. S'il n'est toujours pas trouvé, JavaScript génère une ReferenceErrorexception.
Lors de l'attribution d'un identifiant, JavaScript suit exactement le même processus pour récupérer cet identifiant, sauf que s'il n'est pas trouvé dans la portée globale , il créera la "variable" dans la portée où elle a été créée. En conséquence, une variable jamais déclarée sera globale, si elle est assignée. Déclarer une variable (avec le mot-clé var) dans la portée globale (c'est-à-dire en dehors de tout corps de fonction (ou bloc dans le cas de let/const)), assigner un identifiant jamais déclaré ou ajouter une propriété à l' objet global (généralement window ) créera également une nouvelle variable globale.
Notez que le mode strict de JavaScript interdit l'affectation d'une variable non déclarée, ce qui évite la pollution de l'espace de noms global.
Exemples
Voici quelques exemples de déclarations de variables et de portée :
var x1 = 0 ; // Une variable globale, car elle n'est dans aucune fonction let x2 = 0 ; // Également globale, cette fois car elle n'est dans aucun bloc fonction f () { var z = 'foxes' , r = 'birds' ; // 2 variables locales m = 'fish' ; // globale, car elle n'était déclarée nulle part auparavant function child () { var r = 'monkeys' ; // Cette variable est locale et n'affecte pas les "oiseaux" r de la fonction parent. z = 'penguins' ; // Fermeture : La fonction enfant peut accéder aux variables de la fonction parent. } twenty = 20 ; // Cette variable est déclarée sur la ligne suivante, mais utilisable n'importe où dans la fonction, même avant, comme ici var twenty ; enfant (); return x1 + x2 ; // Nous pouvons utiliser x1 et x2 ici, car ils sont globaux } f (); console . log ( z ); // Cette ligne va générer une exception ReferenceError, car la valeur de z n'est plus disponible
for ( let i = 0 ; i < 10 ; i ++ ) console . log ( i ); console . log ( i ); // génère une ReferenceError : i n'est pas défini
for ( const i = 0 ; i < 10 ; i ++ ) console . log ( i ); // génère une TypeError : Affectation à une variable constante for ( const i de [ 1 , 2 , 3 ]) console . log ( i ); // ne lèvera pas d'exception. i n'est pas réaffecté mais recréé à chaque itération const pi ; // génère une SyntaxError : initialiseur manquant dans la déclaration const
Types de données primitifs
Le langage JavaScript fournit six types de données primitifs :
- Indéfini
- Nombre
- Grand Int
- Chaîne
- Booléen
- Symbole
Certains types de données primitifs fournissent également un ensemble de valeurs nommées qui représentent l'étendue des limites du type. Ces valeurs nommées sont décrites dans les sections appropriées ci-dessous.
Indéfini
La valeur « undefined » est attribuée à toutes les variables non initialisées et est également renvoyée lors de la vérification des propriétés d'objet qui n'existent pas. Dans un contexte booléen, la valeur undefined est considérée comme une valeur fausse.
Remarque : undefined est considéré comme un véritable type primitif. À moins d'être explicitement convertie, la valeur undefined peut se comporter de manière inattendue par rapport à d'autres types évalués à false dans un contexte logique.
let test ; // variable déclarée, mais non définie, ... // ... définie sur la valeur d'undefined const testObj = {}; console . log ( test ); // la variable de test existe, mais la valeur n'est pas ... // ... définie, affiche undefined console . log ( testObj . myProp ); // testObj existe, la propriété n'existe pas, ... // ... affiche undefined console . log ( undefined == null ); // type non appliqué pendant la vérification, affiche true console . log ( undefined === null ); // type appliqué pendant la vérification, affiche false
Remarque : il n'existe pas de littéral de langage intégré pour undefined. Il n'existe donc pas de moyen infaillible de vérifier si une variable est undefined, car dans les versions antérieures à ECMAScript 5, il était légal d'écrire . Une approche plus robuste consiste à comparer en utilisant . (x===undefined)varundefined="I'm defined now";(typeofx==='undefined')
Des fonctions comme celle-ci ne fonctionneront pas comme prévu :
function isUndefined ( x ) { let u ; return x === u ; } // comme ça... function isUndefined ( x ) { return x === void 0 ; } // ... ou ce deuxième function isUndefined ( x ) { return ( typeof x ) === "undefined" ; } // ... ou ce troisième
Ici, l'appel isUndefined(my_var)génère une ReferenceError si my_var est un identifiant inconnu, alors que ce n'est pas le cas. typeofmy_var==='undefined'
Nombre
Les nombres sont représentés en binaire sous forme de doubles à virgule flottante IEEE 754. Bien que ce format offre une précision de près de 16 chiffres significatifs , il ne peut pas toujours représenter exactement les nombres réels, y compris les fractions.
Cela devient un problème lors de la comparaison ou du formatage de nombres. Par exemple :
console . log ( 0.2 + 0.1 === 0.3 ); // affiche false console . log ( 0.94 - 0.01 ); // affiche 0.9299999999999999
Par conséquent, une routine telle que la méthode toFixed() doit être utilisée pour arrondir les nombres chaque fois qu'ils sont formatés pour la sortie.
Les nombres peuvent être spécifiés dans l'une de ces notations :
345 ; // un "entier", bien qu'il n'y ait qu'un seul type numérique en JavaScript 34.5 ; // un nombre à virgule flottante 3.45e2 ; // un autre nombre à virgule flottante, équivalent à 345 0b1011 ; // un entier binaire égal à 11 0o377 ; // un entier octal égal à 255 0xFF ; // un entier hexadécimal égal à 255, chiffres représentés par les ... // ... lettres AF peuvent être en majuscules ou en minuscules
Il existe également un séparateur numérique, _ (le trait de soulignement), introduit dans ES2021 :
// Remarque : la syntaxe Wikipédia ne prend pas encore en charge les séparateurs numériques 1 _000_000_000 ; // Utilisé avec les grands nombres 1 _000_000 .5 ; // Prise en charge des décimales 1 _000e1_000 ; // Prise en charge des exposants // Prise en charge des valeurs binaires, octales et hexadécimales 0b0000 _0000_0101_1011 ; 0o0001 _3520_0237_1327 ; 0xFFFF _FFFF_FFFF_FFFE ; // Mais vous ne pouvez pas les utiliser à côté d'une partie de nombre non numérique, ni au début ou à la fin _12 ; // La variable n'est pas définie (le trait de soulignement en fait un identifiant de variable) 12 _ ; // Erreur de syntaxe (ne peut pas être à la fin des nombres) 12 _ .0 ; // Erreur de syntaxe (il n'est pas logique de mettre un séparateur à côté de la virgule décimale) 12. _0 ; // Erreur de syntaxe 12 e_6 ; // Erreur de syntaxe (à côté de "e", un non-chiffre. Il n'est pas logique de mettre un séparateur au début) 1000 ____0000 ; // Erreur de syntaxe (à côté de "_", un non-chiffre. Un seul séparateur à la fois est autorisé
Les étendues +∞ , −∞ et NaN (Not a Number) du type numérique peuvent être obtenues par deux expressions de programme :
Infini ; // infini positif (négatif obtenu avec -Infinity par exemple) NaN ; // La valeur Not-A-Number, également renvoyée en cas d'échec dans ... // ... conversions de chaîne en nombre
L'infini et NaN sont des nombres :
typeof Infinity ; // renvoie "nombre" typeof NaN ; // renvoie "nombre"
Ces trois valeurs spéciales correspondent et se comportent comme le décrit la norme IEEE-754 .
Le constructeur Number (utilisé comme fonction), ou un unaire + ou -, peut être utilisé pour effectuer une conversion numérique explicite :
const maChaîne = "123.456" ; const monNuméro1 = Nombre ( maChaîne ); const monNuméro2 = + maChaîne ;
Lorsqu'il est utilisé comme constructeur, un objet wrapper numérique est créé (bien qu'il soit de peu d'utilité) :
const myNumericWrapper = nouveau numéro ( 123.456 );
Cependant, NaN n'est pas égal à lui-même :
const nan = NaN ; consoler . journal ( NaN == NaN ); // fausse console . journal ( NaN === NaN ); // fausse console . journal ( NaN !== NaN ); // vraie console . journal ( nan !== nan ); // vrai // Vous pouvez utiliser les méthodes isNaN pour vérifier NaN console . log ( isNaN ( "converti en NaN" )); // vrai console . log ( isNaN ( NaN )); // vrai console . log ( Number . isNaN ( "non converti" )); // faux console . log ( Number . isNaN ( NaN )); // vrai
Grand Int
Les BigInts peuvent être utilisés pour des entiers arbitrairement grands . En particulier les nombres entiers supérieurs à 2 53 - 1, qui est le plus grand nombre que JavaScript peut représenter de manière fiable avec la primitive Number et représenté par la constante Number.MAX_SAFE_INTEGER.
Lors de la division des BigInts, les résultats sont tronqués .
Chaîne
Une chaîne en JavaScript est une séquence de caractères. En JavaScript, les chaînes peuvent être créées directement (en tant que littéraux) en plaçant la série de caractères entre guillemets doubles (") ou simples ('). Ces chaînes doivent être écrites sur une seule ligne, mais peuvent inclure des caractères de nouvelle ligne échappés (tels que ). La norme JavaScript autorise le caractère de guillemet inverse (`, également appelé accent grave ou backtick) pour citer des chaînes littérales multilignes, ainsi que des littéraux de modèle, qui permettent l'interpolation d'expressions évaluées par contrainte de type dans une chaîne.
const greeting = "Bonjour, monde !" ; const anotherGreeting = 'Salutations, peuple de la Terre.' ; const aMultilineGreeting = `Cordialement, John Doe.` // Les modèles littéraux forcent le type des expressions évaluées et les interpolent dans la chaîne. const templateLiteral = `Voici ce qui est stocké dans anotherGreeting : ${ anotherGreeting } .` ; console . log ( templateLiteral ); // 'Voici ce qui est stocké dans anotherGreeting : 'Salutations, peuple de la Terre.''
Les caractères individuels d'une chaîne sont accessibles à l'aide de la méthode charAt (fournie par String.prototype ). Il s'agit de la méthode privilégiée pour accéder à des caractères individuels d'une chaîne, car elle fonctionne également dans les navigateurs non modernes :
const h = salutation . charAt ( 0 );
Dans les navigateurs modernes, les caractères individuels d'une chaîne sont accessibles (sous forme de chaînes contenant un seul caractère) via la même notation que les tableaux :
const h = salutation [ 0 ];
Cependant, les chaînes JavaScript sont immuables :
salutation [ 0 ] = "H" ; // Échoue.
L'application de l'opérateur d'égalité (« == ») à deux chaînes renvoie true, si les chaînes ont le même contenu, c'est-à-dire : de même longueur et contenant la même séquence de caractères (la casse est importante pour les alphabets). Ainsi :
const x = "Monde" ; const compare1 = ( "Bonjour, " + x == "Bonjour, Monde" ); // Ici compare1 contient true. const compare2 = ( "Bonjour, " + x == "Bonjour, Monde" ); // Ici compare2 contient ... // ... false puisque les ... // ... premiers caractères ... // ... des deux opérandes ... // ... ne sont pas de la même casse.
Les citations du même type ne peuvent pas être imbriquées à moins qu'elles ne soient échappées .
laissez x = '"Bonjour le monde !" dit-il.' ; // Très bien. x = Bonjour le monde ! " dit-il." ; // Pas bien. x = "\"Bonjour le monde !" dit-il." ; // Fonctionne en échappant " avec \"
Le constructeur String crée un objet chaîne (un objet enveloppant une chaîne) :
const greeting = new String ( "Bonjour, tout le monde !" );
Ces objets ont une méthode valueOf renvoyant la chaîne primitive qui les entoure :
const s = new String ( "Bonjour !" ); typeof s ; // Est 'object'. typeof s . valueOf (); // Est 'string'.
L'égalité entre deux objets String ne se comporte pas comme avec les primitives de chaîne :
const s1 = new String ( "Bonjour !" ); const s2 = new String ( "Bonjour !" ); s1 == s2 ; // Est faux, car ce sont deux objets distincts. s1 . valueOf () == s2 . valueOf (); // Est vrai.
Booléen
JavaScript fournit un type de données booléen avec des littéraux true et false . L' opérateur typeof renvoie la chaîne « boolean » pour ces types primitifs . Lorsqu'ils sont utilisés dans un contexte logique, 0 , -0 , null , NaN , undefined et la chaîne vide ( ) sont évalués comme false en raison de la conversion automatique de type . Toutes les autres valeurs (le complément de la liste précédente) sont évaluées comme true , y compris les chaînes « 0 » , « false » et tout objet.
Conversion de type
La coercition de type automatique par les opérateurs de comparaison d'égalité ( ==et !=) peut être évitée en utilisant les opérateurs de comparaison de type vérifié ( ===et !==).
Lorsque la conversion de type est requise, JavaScript convertit les opérandes Boolean , Number , String ou Object comme suit :
- Nombre et chaîne
- La chaîne est convertie en valeur numérique. JavaScript tente de convertir le littéral numérique de chaîne en une valeur de type numérique. Tout d'abord, une valeur mathématique est dérivée du littéral numérique de chaîne. Ensuite, cette valeur est arrondie à la valeur de type numérique la plus proche.
- Booléen
- Si l'un des opérandes est booléen, l'opérande booléen est converti en 1 s'il est vrai , ou en 0 s'il est faux .
- Objet
- Si un objet est comparé à un nombre ou à une chaîne, JavaScript tente de renvoyer la valeur par défaut de l'objet. Un objet est converti en une valeur de chaîne ou de nombre primitive, à l'aide des méthodes .valueOf() ou .toString() de l'objet. En cas d'échec, une erreur d'exécution est générée.
Conversion de type booléen
Douglas Crockford préconise les termes « true » et « false » pour décrire le comportement des valeurs de différents types lorsqu'elles sont évaluées dans un contexte logique, en particulier en ce qui concerne les cas limites. Les opérateurs logiques binaires renvoyaient une valeur booléenne dans les premières versions de JavaScript, mais ils renvoient désormais l'un des opérandes à la place. L'opérande de gauche est renvoyé s'il peut être évalué comme : false , dans le cas d' une conjonction : ( ), ou true , dans le cas d' une disjonction : ( ) ; sinon, l'opérande de droite est renvoyé. La coercition de type automatique par les opérateurs de comparaison peut différer pour les cas d'opérandes mixtes booléens et compatibles avec les nombres (y compris les chaînes qui peuvent être évaluées comme un nombre, ou les objets qui peuvent être évalués comme une telle chaîne), car l'opérande booléen sera comparé comme une valeur numérique. Cela peut être inattendu. Une expression peut être explicitement convertie en une primitive booléenne en doublant l' opérateur de négation logique : ( !! ), en utilisant la fonction Boolean() ou en utilisant l' opérateur conditionnel : ( ). a && ba || bc ? t : f
// Coercition de type automatique console . log ( true == 2 ); // faux... vrai → 1 !== 2 ← 2 console . log ( false == 2 ); // faux... faux → 0 !== 2 ← 2 console . log ( true == 1 ); // vrai.... vrai → 1 === 1 ← 1 console . log ( false == 0 ); // vrai.... faux → 0 === 0 ← 0 console . log ( true == "2" ); // faux... vrai → 1 !== 2 ← "2" console . log ( false == "2" ); // faux... faux → 0 !== 2 ← "2" console . log ( true == "1" ); // vrai.... vrai → 1 === 1 ← "1" console . journal ( faux == "0" ); // vrai.... faux → 0 === 0 ← "0" console . journal ( faux == ); // vrai.... faux → 0 === 0 ← "" console . journal ( faux == NaN ); // faux... faux → 0 !== NaN console . log ( NaN == NaN ); // false...... NaN n'est équivalent à rien, y compris NaN. // Comparaison de type vérifiée (pas de conversion de types et de valeurs) console . log ( true === 1 ); // false...... les types de données ne correspondent pas // Coercition de type explicite console . log ( true === !! 2 ); // true.... les types de données et les valeurs correspondent console . log ( true === !! 0 ); // false... les types de données correspondent, mais les valeurs diffèrent console . log ( 1 ? true : false ); // true.... seuls ±0 et NaN sont des nombres "falsifiés" console . log ( "0" ? true : false ); // true.... seule la chaîne vide est "falsifiée" console . log ( Boolean ({})); // true.... tous les objets sont "vrais"
L'opérateur new peut être utilisé pour créer un wrapper d'objet pour une primitive booléenne. Cependant, l' opérateur typeof ne renvoie pas boolean pour le wrapper d'objet, il renvoie object . Étant donné que tous les objets sont évalués comme true , une méthode telle que .valueOf() ou .toString() doit être utilisée pour récupérer la valeur enveloppée. Pour une coercition explicite vers le type booléen, Mozilla recommande d' utiliser la fonction Boolean() (sans new ) de préférence à l'objet booléen.
const b = new Boolean ( false ); // Objet false {} const t = Boolean ( b ); // Booléen true const f = Boolean ( b.valueOf ( ) ); // Booléen false let n = new Boolean ( b ) ; // Non recommandé n = new Boolean ( b.valueOf ( )); // Préféré if ( 0 || - 0 || || null || undefined || b . valueOf () || ! new Boolean () || ! t ) { console . log ( "Jamais ceci" ); } else if ([] && {} && b && typeof b === "object" && b . toString () === "false" ) { console . log ( "Toujours ceci" ); }
Symbole
Nouveau dans ECMAScript6. Un symbole est un identifiant unique et immuable.
Exemple:
soit x = Symbole ( 1 ); const y = Symbole ( 1 ); x === y ; // => faux const objetsymbole = {}; const objetnormal = {}; // puisque x et y sont uniques, // ils peuvent être utilisés comme clés uniques dans un objet symbolObject [ x ] = 1 ; symbolObject [ y ] = 2 ; ObjetSymbole [ x ]; // => 1 ObjetSymbole [ y ]; // => 2 // par rapport aux touches numériques normales normalObject [ 1 ] = 1 ; normalObject [ 1 ] = 2 ; // remplace la valeur de 1 normalObject [ 1 ]; // => 2 // changer la valeur de x ne change pas la clé stockée dans l'objet x = Symbol ( 3 ); symbolObject [ x ]; // => undefined // la modification de x crée simplement un autre symbole unique x = Symbol ( 1 ); symbolObject [ x ]; // => undefined
Il existe également des symboles bien connus .
L'une d'entre elles estSymbol.iterator : si quelque chose implémente Symbol.iterator, c'est itérable :
const x = [ 1 , 2 , 3 , 4 ]; // x est un tableau x [ Symbol . iterator ] === Array . prototype [ Symbol . iterator ]; // et les tableaux sont itérables const xIterator = x [ Symbol . iterator ](); // La fonction [Symbol.iterator] doit fournir un itérateur pour x xIterator . next (); // { valeur : 1, done : false } xIterator . next (); // { valeur : 2, done : false } xIterator . next (); // { valeur : 3, done : false } xIterator . next (); // { valeur : 4, done : false } xIterator . next (); // { valeur : undefined, done : true } xIterator . next (); // { valeur : undefined, done : true } // les boucles for..of parcourent automatiquement les valeurs for ( const value of x ) { console . log ( value ); // 1 2 3 4 } // Les ensembles sont également itérables : [ Symbol . iterator ] in Set . prototype ; // true pour ( const valeur de nouveau Set ([ 'apple' , 'orange' ])) { console . log ( valeur ); // "apple" "orange" }
Objets natifs
Le langage JavaScript fournit une poignée d' objets natifs . Les objets natifs JavaScript sont considérés comme faisant partie de la spécification JavaScript. Quel que soit l'environnement JavaScript, cet ensemble d'objets doit toujours être disponible.
Tableau
Un tableau est un objet JavaScript prototypé à partir du Arrayconstructeur spécifiquement conçu pour stocker des valeurs de données indexées par des clés entières. Les tableaux, contrairement au type Object de base, sont prototypés avec des méthodes et des propriétés pour aider le programmeur dans les tâches de routine (par exemple, join, sliceet push).
Comme dans la famille C , les tableaux utilisent un schéma d'indexation basé sur zéro : une valeur insérée dans un tableau vide au moyen de la pushméthode occupe le 0e index du tableau.
const myArray = []; // Pointez la variable myArray vers un tableau nouvellement ... // ... créé et vide myArray . push ( "hello World" ); // Remplissez le prochain index vide, dans ce cas 0 console . log ( myArray [ 0 ]); // Équivalent à console.log("hello World");
Les tableaux ont une lengthpropriété qui est garantie d'être toujours plus grande que le plus grand index entier utilisé dans le tableau. Elle est automatiquement mise à jour si l'on crée une propriété avec un index encore plus grand. L'écriture d'un nombre plus petit dans la lengthpropriété supprimera les index plus grands.
Les éléments de Arrays peuvent être accessibles à l'aide de la notation d'accès aux propriétés d'objet normale :
myArray [ 1 ]; // le 2ème élément dans myArray myArray [ "1" ];
Les deux exemples ci-dessus sont équivalents. Il n'est pas possible d'utiliser la notation « point » ou des chaînes avec des représentations alternatives du nombre :
myArray .1 ; // erreur de syntaxe myArray [ "01" ]; // différent de myArray[1]
La déclaration d'un tableau peut utiliser soit un Arraylittéral, soit le Arrayconstructeur :
laisse monTableau ; // Littéraux de tableau myArray = [ 1 , 2 ]; // longueur de 2 myArray = [ 1 , 2 ,]; // même tableau - Vous pouvez également avoir une virgule supplémentaire à la fin // Il est également possible de ne pas remplir certaines parties du tableau myArray = [ 0 , 1 , /* trou */ , /* trou */ , 4 , 5 ]; // longueur de 6 myArray = [ 0 , 1 , /* trou */ , /* trou */ , 4 , 5 ,]; // même tableau myArray = [ 0 , 1 , /* trou */ , /* trou */ , 4 , 5 , /* trou */ ,]; // longueur de 7 // Avec le constructeur myArray = new Array ( 0 , 1 , 2 , 3 , 4 , 5 ); // longueur de 6 myArray = new Array ( 365 ); // un tableau vide de longueur 365
Les tableaux sont implémentés de telle sorte que seuls les éléments définis utilisent la mémoire ; ce sont des « tableaux clairsemés ». La définition de et n'utilise de l'espace que pour ces deux éléments, comme tout autre objet. La longueur du tableau sera toujours indiquée comme étant de 58. La longueur maximale d'un tableau est de 4 294 967 295, ce qui correspond à un nombre binaire de 32 bits (1111111111111111111111111111111111) 2 . myArray[10]='someThing'myArray[57]='somethingOther'length
On peut utiliser le littéral de déclaration d'objet pour créer des objets qui se comportent un peu comme des tableaux associatifs dans d'autres langages :
const dog = { color : "brown" , size : "large" }; dog [ "color" ]; // donne "brown" dog . color ; // donne également "brown"
On peut utiliser les littéraux de déclaration d'objet et de tableau pour créer rapidement des tableaux associatifs, multidimensionnels ou les deux. (Techniquement, JavaScript ne prend pas en charge les tableaux multidimensionnels, mais on peut les imiter avec des tableaux de tableaux.)
const chats = [{ couleur : "marron" , taille : "grand" }, { couleur : "noir" , taille : "petit" }]; chats [ 0 ][ "taille" ]; // donne "grand" const dogs = { rover : { color : "brown" , size : "large" }, spot : { color : "black" , size : "small" }}; dogs [ "spot" ][ "size" ]; // donne "small" dogs . rover . color ; // donne "brown"
Date
Un Dateobjet stocke un nombre de millisecondes signé, zéro représentant 1970-01-01 00:00:00 UT et une plage de ±10 8 jours. Il existe plusieurs façons de fournir des arguments au Dateconstructeur. Notez que les mois sont basés sur zéro.
new Date (); // crée une nouvelle instance de Date représentant l'heure/date actuelle. new Date ( 2010 , 2 , 1 ); // crée une nouvelle instance de Date représentant 2010-Mar-01 00:00:00 new Date ( 2010 , 2 , 1 , 14 , 25 , 30 ); // crée une nouvelle instance de Date représentant 2010-Mar-01 14:25:30 new Date ( "2010-3-1 14:25:30" ); // crée une nouvelle instance de Date à partir d'une chaîne.
Des méthodes pour extraire des champs sont fournies, ainsi qu'un toString:
const d = new Date ( 2010 , 2 , 1 , 14 , 25 , 30 ); // 2010-Mar-01 14:25:30; // Affiche '2010-3-1 14:25:30': console . log ( d . getFullYear () + '-' + ( d . getMonth () + 1 ) + '-' + d . getDate () + ' ' + d . getHours () + ':' + d . getMinutes () + ':' + d . getSeconds ()); // La fonction toString intégrée renvoie quelque chose comme « Lun Mar 01 2010 14:25:30 GMT-0500 (EST) » : console . log ( d );
Erreur
Des messages d'erreur personnalisés peuvent être créés à l'aide de la Errorclasse :
lancer une nouvelle erreur ( "Quelque chose s'est mal passé." );
Ceux-ci peuvent être interceptés par des blocs try...catch...finally comme décrit dans la section sur la gestion des exceptions.
Mathématiques
L' objet Math contient diverses constantes mathématiques (par exemple, π ) et fonctions (par exemple, cosinus). (Notez que l' objet Math n'a pas de constructeur, contrairement à Array ou Date . Toutes ses méthodes sont « statiques », c'est-à-dire des méthodes « de classe ».) Toutes les fonctions trigonométriques utilisent des angles exprimés en radians , et non en degrés ou en grades .
| Propriété | Valeur renvoyée arrondie à 5 chiffres |
Description |
|---|---|---|
| Math.E | 2.7183 | e : Base du logarithme naturel |
| Math.LN2 | 0,69315 | Logarithme naturel de 2 |
| Mathématiques.LN10 | 2.3026 | Logarithme naturel de 10 |
| Math.LOG2E | 1.4427 | Logarithme à base 2 de e |
| Math.LOG10E | 0,43429 | Logarithme à base 10 de e |
| Math.PI | 3.14159 | π : circonférence/diamètre d'un cercle |
| Math.SQRT1_2 | 0,70711 | Racine carrée de ½ |
| Math.SQRT2 | 1.4142 | Racine carrée de 2 |
| Exemple | Valeur renvoyée arrondie à 5 chiffres |
Description |
|---|---|---|
| Math.abs(-2.3) | 2.3 | Valeur absolue |
| Math.acos(Math.SQRT1_2) | 0,78540 rad = 45° | Arc cosinus |
| Math.asin(Math.SQRT1_2) | 0,78540 rad = 45° | Arc sinus |
| Math.atan(1) | 0,78540 rad = 45° | Demi-cercle arctangente ( à ) |
| Math.atan2(-3.7, -3.7) | −2,3562 rad =−135° | Arctangente du cercle entier ( à ) |
| Math.ceil(1.1) | 2 | Plafond : arrondir au plus petit entier ≥ argument |
| Math.cos(Math.PI/4) | 0,70711 | Cosinus |
| Math.exp(1) | 2.7183 | Fonction exponentielle : e élevé à cette puissance |
| Math.floor(1.9) | 1 | Plancher : arrondir au plus grand entier inférieur ≤ argument |
| Math.log(Math.E) | 1 | Logarithme naturel, base e |
| Math.max(1, -2) | 1 | Maximum : (x > y) ? x : y |
| Math.min(1, -2) | −2 | Minimum : (x < y) ? x : y |
| Math.pow(-3, 2) | 9 | Exponentiation (élevée à la puissance de) : Math.pow(x, y) donne x y |
| Math.aléatoire() | par exemple 0,17068 | Nombre pseudo-aléatoire compris entre 0 (inclus) et 1 (exclu) |
| Math.round(1.5) | 2 | Arrondir à l'entier le plus proche ; les demi-fractions sont arrondies au chiffre supérieur (par exemple, 1,5 arrondi à 2) |
| Math.sin(Math.PI/4) | 0,70711 | Sinus |
| Math.sqrt(49) | 7 | Racine carrée |
| Math.tan(Math.PI/4) | 1 | Tangente |
Expression régulière
/expression/ . test ( string ); // renvoie le booléen "string" . search ( /expression/ ); // renvoie le numéro de position "string" . replace ( /expression/ , replacement ); // Voici quelques exemples if ( /Tom/ . test ( "Mon nom est Tom" )) console . log ( "Bonjour Tom !" ); console . log ( "Mon nom est Tom" . search ( /Tom/ )); // == 11 (lettres avant Tom) console . log ( "Mon nom est Tom" . replace ( /Tom/ , "John" )); // == "Mon nom est John"
Classes de personnages
// \d - chiffre // \D - non-chiffre // \s - espace // \S - non-espace // \w - caractère de mot // \W - non-mot // [ ] - l'un de // [^] - l'un de // - - plage if ( /\d/ . test ( '0' )) console . log ( 'Chiffre' ); if ( /[0-9]/ . test ( '6' )) console . log ( 'Chiffre ' ); if ( /[13579]/ . test ( '1' )) console . log ( 'Nombre impair' ); if ( /\S\S\s\S\S\S\S/ . test ( 'Mon nom' )) console . log ( 'Format OK' ); if ( /\w\w\w/ . test ( 'Tom' )) console . log ( 'Bonjour Tom' ); if ( /[a-zA-Z]/ . test ( 'B' )) console . log ( 'Lettre' );
Correspondance des caractères
// A...Z a...z 0...9 - alphanumérique // \u0000...\uFFFF - hexadécimal Unicode // \x00...\xFF - hexadécimal ASCII // - tabulation // - nouvelle ligne // - CR // . - n'importe quel caractère // | - OU if ( /Tm/ . test ( 'Tom' )) console . log ( 'Salut Tom, Tam ou Tim' ); if ( /A|B/ . test ( "A" )) console . log ( 'A ou B' );
Répétiteurs
// ? - 0 ou 1 correspondance // * - 0 ou plus // + - 1 ou plus // {n} - exactement n // {n,} - n ou plus // {0,n} - n ou moins // {n,m} - plage n à m if ( /ab?c/ . test ( "ac" )) console . log ( "OK" ); // correspondance : "ac", "abc" if ( /ab*c/ . test ( "ac" )) console . log ( "OK" ); // correspondance : "ac", "abc", "abbc", "abbbc" etc. if ( /ab+c/ . test ( "abc" )) console . log ( "OK" ); // correspondance : "abc", "abbc", "abbbc" etc. if ( /ab{3}c/ . test ( "abbbc" )) console . log ( "OK" ); // correspondance : "abbbc" if ( /ab{3,}c/ . test ( "abbbc" )) console . log ( "OK" ); // match : "abbbbc", "abbbbc", "abbbbbc" etc. if ( /ab{1,3}c/ . test ( "abc" )) console . journal ( "OK" ); // correspondance : "abc", "abbc", "abbbc"
Ancres
// ^ - la chaîne commence par // $ - la chaîne se termine par if ( /^My/ . test ( "Mon nom est Tom" )) console . log ( "Salut !" ); if ( /Tom$/ . test ( "Mon nom est Tom" )) console . log ( "Salut Tom !" );
Sous-expression
// ( ) - regroupe les caractères if ( /water(mark)?/ . test ( "watermark" )) console . log ( "Voici de l'eau !" ); // correspondance : "eau", "watermark", if ( /(Tom)|(John)/ . test ( "John" )) console . log ( "Salut Tom ou John !" );
Drapeaux
// /g - global // /i - ignorer les majuscules/minuscules // /m - autoriser les correspondances à s'étendre sur plusieurs lignes console . log ( "salut tom !" . replace ( /Tom/i , "John" )); // == "salut John !" console . log ( "ratatam" . replace ( /ta/ , "tu" )); // == "ratutam" console . log ( "ratatam" . replace ( /ta/g , "tu" )); // == "ratutum"
Méthodes avancées
mon_tableau = ma_chaîne . split ( mon_délimiteur ); // exemple mon_tableau = "chien,chat,vache" . split ( "," ); // mon_tableau==["chien","chat","vache"]; my_array = my_string . match ( my_expression ); // exemple my_array = "Nous commençons à 11h30, 12h15 et 16h45" . match ( /\d\d:\d\d/g ); // my_array==["11:30","12:15","16:45"];
Capture de groupes
const myRe = /(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/ ; const results = myRe . exec ( "La date et l'heure sont 2009-09-08 09:37:08." ); if ( results ) { console . log ( "Correspondance : " + results [ 0 ]); // Correspondance complète const my_date = results [ 1 ]; // Premier groupe == "2009-09-08" const my_time = results [ 2 ]; // Deuxième groupe == "09:37:08" console . log ( `Il est ${ my_time } le ${ my_date } ` ); } else console . log ( "Aucune date valide n'a été trouvée !" );
Fonction
Chaque fonction en JavaScript est une instance du Functionconstructeur :
// x, y est l'argument. 'return x + y' est le corps de la fonction, qui est le dernier dans la liste des arguments. const add = new Function ( 'x' , 'y' , 'return x + y' ); add ( 1 , 2 ); // => 3
La fonction d'ajout ci-dessus peut également être définie à l'aide d'une expression de fonction :
const ajouter = fonction ( x , y ) { retourner x + y ; }; ajouter ( 1 , 2 ); // => 3
Dans ES6, la syntaxe de la fonction fléchée a été ajoutée, ce qui permet aux fonctions qui renvoient une valeur d'être plus concises. Elles conservent également la propriété thisde l'objet global au lieu de l'hériter de l'endroit où il a été appelé / de la manière dont il a été appelé, contrairement à l' function() {}expression.
const add = ( x , y ) => { return x + y ;}; // les valeurs peuvent également être renvoyées implicitement (c'est-à-dire qu'aucune instruction de retour n'est nécessaire) const addImplicit = ( x , y ) => x + y ; ajouter ( 1 , 2 ); // => 3 addImplicit ( 1 , 2 ) // => 3
Pour les fonctions qui doivent être hissées, il existe une expression distincte :
fonction ajouter ( x , y ) { retour x + y ; } ajouter ( 1 , 2 ); // => 3
Le levage vous permet d'utiliser la fonction avant qu'elle ne soit « déclarée » :
add ( 1 , 2 ); // => 3, pas une fonction ReferenceError add ( x , y ) { return x + y ; }
Une instance de fonction possède des propriétés et des méthodes.
fonction soustraire ( x , y ) { retour x - y ; } console . log ( subtract . length ); // => 2, arité de la fonction (nombre d'arguments) console . log ( subtract . toString ()); /* "fonction soustraire(x, y) { retour x - y; }" */
Opérateurs
L'opérateur '+' est surchargé : il est utilisé pour la concaténation de chaînes et l'addition arithmétique. Cela peut poser des problèmes en cas de mélange involontaire de chaînes et de nombres. En tant qu'opérateur unaire, il peut convertir une chaîne numérique en nombre.
// Concaténer 2 chaînes console . log ( 'He' + 'llo' ); // affiche Hello // Ajouter deux nombres console . log ( 2 + 6 ); // affiche 8 // L'ajout d'un nombre et d'une chaîne entraîne une concaténation (de gauche à droite) console . log ( 2 + '2' ); // affiche 22 console . log ( '$' + 3 + 4 ); // affiche 34 $, mais 7 $ était peut-être attendu console . log ( '$' + ( 3 + 4 )); // affiche 7 $ console . log ( 3 + 4 + '7' ); // affiche 77, les nombres restent des nombres jusqu'à ce qu'une chaîne soit ajoutée // Convertir une chaîne en nombre en utilisant le signe unaire plus console . log ( + '2' === 2 ); // affiche true console . log ( + 'Hello' ); // affiche NaN
De même, l'opérateur '*' est surchargé : il peut convertir une chaîne en nombre.
console . log ( 2 + '6' * 1 ); // affiche 8 console . log ( 3 * '7' ); // 21 console . log ( '3' * '7' ); // 21 console . log ( 'hello' * 'world' ); // affiche NaN
Arithmétique
JavaScript prend en charge les opérateurs arithmétiques binaires suivants :
+ |
ajout |
- |
soustraction |
* |
multiplication |
/ |
division (renvoie une valeur à virgule flottante) |
% |
modulo (renvoie le reste) |
** |
exponentiation |
JavaScript prend en charge les opérateurs arithmétiques unaires suivants :
+ |
conversion unaire de chaîne en nombre |
- |
négation unaire (inverse le signe) |
++ |
incrément (peut être un préfixe ou un suffixe) |
-- |
décrémenter (peut être un préfixe ou un suffixe) |
soit x = 1 ; console . log ( ++ x ); // x devient 2 ; affiche 2 console . log ( x ++ ); // affiche 2 ; x devient 3 console . log ( x ); // x est 3 ; affiche 3 console . log ( x -- ); // affiche 3 ; x devient 2 console . log ( x ); // affiche 2 ; x est 2 console . log ( -- x ); // x devient 1 ; affiche 1
L'opérateur modulo affiche le reste après division par le module. Si des nombres négatifs sont impliqués, la valeur renvoyée dépend de l'opérande.
const x = 17 ; console . log ( x % 5 ); // affiche 2 console . log ( x % 6 ); // affiche 5 console . log ( - x % 5 ); // affiche -2 console . log ( - x %- 5 ); // affiche -2 console . log ( x %- 5 ); // affiche 2
Pour toujours renvoyer un nombre non négatif, ajoutez à nouveau le module et appliquez à nouveau l'opérateur modulo :
const x = 17 ; console . log (( - x % 5 + 5 ) % 5 ); // affiche 3
Vous pourriez également faire :
const x = 17 ; console . log ( Math . abs ( - x % 5 )); // également 3
Affectation
= |
attribuer |
+= |
ajouter et attribuer |
-= |
soustraire et attribuer |
*= |
multiplier et attribuer |
/= |
diviser et attribuer |
%= |
modulo et assigner |
**= |
exponentiation et assignation |
Affectation de types primitifs
soit x = 9 ; x += 1 ; console . log ( x ); // affiche : 10 x *= 30 ; console . log ( x ); // affiche : 300 x /= 6 ; console . log ( x ); // affiche : 50 x -= 3 ; console . log ( x ); // affiche : 47 x %= 7 ; console . log ( x ); // affiche : 5
Affectation des types d'objets
/** * Pour apprendre les objets JavaScript... */ const object_1 = { a : 1 }; // affecte une référence de l'objet nouvellement créé à object_1 let object_2 = { a : 0 }; let object_3 = object_2 ; // object_3 référence le même objet que object_2 object_3 . a = 2 ; message ( ); // affiche 1 2 2 object_2 = object_1 ; // object_2 référence maintenant le même objet que object_1 // object_3 référence toujours ce que object_2 référençait avant message (); // affiche 1 1 2 object_2 . a = 7 ; // modifie object_1 message (); // affiche 7 7 2 object_3 . a = 5 ; // object_3 ne change pas le message object_2 (); // affiche 7 7 5 objet_3 = objet_2 ; objet_3 . a = 4 ; // objet_3 modifie les messages objet_1 et objet_2 (); // affiche 4 4 4 /** * Imprime le message console.log */ function message () { console . log ( object_1 . a + + object_2 . a + + object_3 . a ); }
Mission de déstructuration
Dans le JavaScript de Mozilla, depuis la version 1.7, l'affectation par déstructuration permet d'affecter des parties de structures de données à plusieurs variables à la fois. Le côté gauche d'une affectation est un motif qui ressemble à un objet/tableau littéral imbriqué arbitrairement contenant des valeurs l-l à ses extrémités qui doivent recevoir les sous-structures de la valeur affectée.
soit a , b , c , d , e ; [ a , b , c ] = [ 3 , 4 , 5 ]; console . log ( ` ${ a } , ${ b } , ${ c } ` ); // affiche : 3,4,5 e = { foo : 5 , bar : 6 , baz : [ 'Baz' , 'Contenu' ]}; const arr = []; ({ baz : [ arr [ 0 ], arr [ 3 ]], foo : a , bar : b } = e ); console . log ( ` ${ a } , ${ b } , ${ arr } ` ); // affiche : 5,6,Baz,,,Contenu [ a , b ] = [ b , a ]; // échange le contenu de a et b console . log ( a + ',' + b ); // affiche : 6,5 [ a , b , c ] = [ 3 , 4 , 5 ]; // permutations [ a , b , c ] = [ b , c , a ]; console . log ( ` ${ a } , ${ b } , ${ c } ` ); // affiche : 4,5,3
Opérateur de propagation/repos
La norme ECMAScript 2015 a introduit l' ...opérateur de tableau « », pour les concepts associés de « syntaxe de propagation » et de « paramètres de repos ». La propagation d'objets a été ajoutée dans ECMAScript 2018.
La syntaxe de propagation fournit une autre façon de déstructurer les tableaux et les objets. Pour les tableaux, elle indique que les éléments doivent être utilisés comme paramètres dans un appel de fonction ou comme éléments dans un littéral de tableau. Pour les objets, elle peut être utilisée pour fusionner des objets ou remplacer des propriétés.
En d'autres termes, " ..." transforme " [...foo]" en " [foo[0], foo[1], foo[2]]", et " this.bar(...foo);" en " this.bar(foo[0], foo[1], foo[2]);", et " { ...bar }" en { prop: bar.prop, prop2: bar.prop2 }.
constante a = [ 1 , 2 , 3 , 4 ]; // Il peut être utilisé plusieurs fois dans la même expression const b = [... a , ... a ]; // b = [1, 2, 3, 4, 1, 2, 3, 4]; // Il peut être combiné avec des éléments non étalés. const c = [ 5 , 6 , ... a , 7 , 9 ]; // c = [5, 6, 1, 2, 3, 4, 7, 9]; // À titre de comparaison, faire cela sans l'opérateur de propagation // crée un tableau imbriqué. const d = [ a , a ]; // d = [[1, 2, 3, 4], [1, 2, 3, 4]] // Cela fonctionne de la même manière avec les appels de fonction fonction foo ( arg1 , arg2 , arg3 ) { console . log ( ` ${ arg1 } : ${ arg2 } : ${ arg3 } ` ); } // Vous pouvez l'utiliser même s'il passe plus de paramètres que la fonction n'en utilisera foo (... une ); // "1:2:3" → foo(a[0], a[1], a[2], a[3]); // Vous pouvez le mélanger avec des paramètres non répartis foo ( 5 , ... une , 6 ); // "5:1:2" → foo(5, a[0], a[1], a[2], a[3], 6); // À titre de comparaison, faire cela sans l'opérateur de propagation // affecte le tableau à arg1 et rien aux autres paramètres. foo ( a ); // "1,2,3,4:indéfini:indéfini" barre constante = { a : 1 , b : 2 , c : 3 }; // Cela copierait l'objet const copie = { ... barre }; // copie = { a: 1, b: 2, c: 3 }; // "b" serait remplacé ici const override = { ... bar , b : 4 }; // override = { a: 1, c: 3, b: 4 }
Lorsqu'il ...est utilisé dans une déclaration de fonction , il indique un paramètre de repos . Le paramètre de repos doit être le dernier paramètre nommé dans la liste des paramètres de la fonction. Il lui sera assigné un Arraycontenant tous les arguments passés à la fonction en excès des autres paramètres nommés. En d'autres termes, il obtient « le reste » des arguments passés à la fonction (d'où son nom).
fonction foo ( a , b , ... c ) { console . log ( c . length ); } foo ( 1 , 2 , 3 , 4 , 5 ); // "3" → c = [3, 4, 5] foo ( 'a' , 'b' ); // "0" → c = []
Les paramètres de repos sont similaires à argumentsl'objet de Javascript, qui est un objet de type tableau contenant tous les paramètres (nommés et sans nom) de l'appel de fonction en cours. argumentsCependant, contrairement à , les paramètres de repos sont de véritables Arrayobjets, de sorte que des méthodes telles que .slice()et .sort()peuvent être utilisées directement sur eux.
Comparaison
== |
égal |
!= |
pas égal |
> |
plus grand que |
>= |
supérieur ou égal à |
< |
moins que |
<= |
inférieur ou égal à |
=== |
identique (égal et de même type) |
!== |
pas identique |
Les variables référençant des objets sont égales ou identiques uniquement si elles référencent le même objet :
const obj1 = { a : 1 }; const obj2 = { a : 1 }; const obj3 = obj1 ; console . log ( obj1 == obj2 ); // faux console . log ( obj3 == obj1 ); // vrai console . log ( obj3 === obj1 ); // vrai
Voir aussi String.
Logique
JavaScript fournit quatre opérateurs logiques :
- négation unaire (
NOT = !a) - disjonction binaire (
OR = a || b) et conjonction (AND = a && b) - conditionnel ternaire (
c ? t : f)
Dans le contexte d'une opération logique, toute expression est évaluée à vrai, à l'exception des suivantes :
- Chaînes :
,'', - Numéros :
0,-0,NaN, - Spécial:
null,undefined, - Booléen :
false.
La fonction booléenne peut être utilisée pour convertir explicitement en une primitive de type Boolean:
// Seules les chaînes vides renvoient false console . log ( Boolean ( ) === false ); console . log ( Boolean ( "false" ) === true ); console . log ( Boolean ( "0" ) === true ); // Seuls zéro et NaN renvoient false console . log ( Boolean ( NaN ) === false ); console . log ( Boolean ( 0 ) === false ); console . log ( Boolean ( - 0 ) === false ); // équivalent à -1*0 console . log ( Boolean ( - 2 ) === true ); // Tous les objets renvoient vrai console . log ( Boolean ( this ) === true ); console . log ( Boolean ( {} ) === true ); console . log ( Boolean ( [ ] ) === true ); // Ces types renvoient false console . log ( Boolean ( null ) === false ); console . log ( Boolean ( undefined ) === false ); // équivalent à Boolean()
L'opérateur NOT évalue son opérande comme un booléen et renvoie la négation. L'utilisation de l'opérateur deux fois de suite, en tant que double négatif , convertit explicitement une expression en une primitive de type booléen :
console . log ( ! 0 === Booléen ( ! 0 )); console . log ( Booléen ( ! 0 ) === !! 1 ); console . log ( !! 1 === Booléen ( 1 )); console . log ( !! 0 === Booléen ( 0 )); console . log ( Booléen ( 0 ) === ! 1 ); console . log ( ! 1 === Booléen ( ! 1 )); console . log ( ! === Booléen ( ! )); console . log ( Booléen ( ! ) === !! "s" ); console . log ( !! "s" === Booléen ( "s" )); console . log ( !! === Booléen ( )); console . log ( Booléen ( ) === ! "s" ); console . log ( ! "s" === Booléen ( ! "s" ));
L'opérateur ternaire peut également être utilisé pour une conversion explicite :
console . log ([] == false ); console . log ([] ? true : false ); // “truthy”, mais la comparaison utilise [].toString() console . log ([ 0 ] == false ); console . log ([ 0 ] ? true : false ); // [0].toString() == "0" console . log ( "0" == false ); console . log ( "0" ? true : false ); // "0" → 0 ... (0 == 0) ... 0 ← false console . log ([ 1 ] == true ); console . log ([ 1 ] ? true : false ); // [1].toString() == "1" console . log ( " 1" == true ); console . log ( "1" ? true : false ); // "1" → 1 ... (1 == 1) ... 1 ← true console . log ([ 2 ] != true ); console . log ([ 2 ] ? true : false ); // [2].toString() == "2" console . log ( "2" != true ); console . log ( "2" ? true : false ); // "2" → 2 ... (2 != 1) ... 1 ← true
Les expressions qui utilisent des fonctionnalités telles que la post-incrémentation ( ) ont un effet secondairei++ anticipé . JavaScript fournit une évaluation en court-circuit des expressions ; l'opérande de droite n'est exécuté que si l'opérande de gauche ne suffit pas à déterminer la valeur de l'expression.
console . log ( a || b ); // Lorsque a est vrai, il n'y a aucune raison d'évaluer b. console . log ( a && b ); // Lorsque a est faux, il n'y a aucune raison d'évaluer b. console . log ( c ? t : f ); // Lorsque c est vrai, il n'y a aucune raison d'évaluer f.
Dans les premières versions de JavaScript et JScript , les opérateurs logiques binaires renvoyaient une valeur booléenne (comme la plupart des langages de programmation dérivés du C). Cependant, toutes les implémentations contemporaines renvoient à la place l'un de leurs opérandes :
console . log ( a || b ); // si a est vrai, renvoie a, sinon renvoie b console . log ( a && b ); // si a est faux, renvoie a, sinon renvoie b
Les programmeurs qui sont plus familiers avec le comportement en C pourraient trouver cette fonctionnalité surprenante, mais elle permet une expression plus concise de modèles comme la fusion nulle :
const s = t || "(par défaut)" ; // attribue t, ou la valeur par défaut, si t est nul, vide, etc.
Affectation logique
??=
|
Affectation nulle |
||=
|
Affectation logique OU |
&&=
|
Logique et affectation |
Au niveau du bit
JavaScript prend en charge les opérateurs binaires au niveau du bit suivants :
& |
ET |
| |
OU |
^ |
XOR |
! |
PAS |
<< |
décalage vers la gauche (remplissage nul à droite) |
>> |
décalage vers la droite (propagation du signe) ; les copies du bit le plus à gauche (bit de signe) sont décalées vers l'intérieur depuis la gauche |
>>> |
Décalage vers la droite (remplissage de zéros à gauche). Pour les nombres positifs, >>et >>>donnent le même résultat. |
Exemples :
const x = 11 & 6 ; console . log ( x ); // 2
JavaScript prend en charge l' opérateur binaire unaire suivant :
~ |
NON (inverse les bits) |
Affectation au niveau du bit
JavaScript prend en charge les opérateurs d’affectation binaires suivants :
&= |
et |
|= |
ou |
^= |
xor |
<<= |
décalage vers la gauche (remplissage nul à droite) |
>>= |
décalage vers la droite (propagation du signe) ; les copies du bit le plus à gauche (bit de signe) sont décalées vers l'intérieur depuis la gauche |
>>>= |
Décalage vers la droite (remplissage de zéros à gauche). Pour les nombres positifs, >>=et >>>=donnent le même résultat. |
Exemples :
soit x = 7 ; console . log ( x ); // 7 x <<= 3 ; console . log ( x ); // 7->14->28->56
Chaîne
= |
affectation |
+ |
enchaînement |
+= |
concaténer et attribuer |
Exemples :
laissez str = "ab" + "cd" ; // "abcd" str += "e" ; // "abcd" const str2 = "2" + 2 ; // "22", pas "4" ou 4.
??
L'opérateur le plus proche de JavaScript?? est , l'« opérateur de coalescence null », qui a été ajouté à la norme dans la 11e édition d' ECMAScript . Dans les versions antérieures, il pouvait être utilisé via un plugin Babel et dans TypeScript . Il évalue son opérande de gauche et, si la valeur de résultat n'est pas « null » ( nullou undefined), prend cette valeur comme résultat ; sinon, il évalue l'opérande de droite et prend la valeur résultante comme résultat.
Dans l'exemple suivant, ala valeur de sera attribuée bsi la valeur de bn'est pas nullou undefined, sinon elle sera attribuée 3.
const a = b ?? 3 ;
Avant l'opérateur de fusion nul, les programmeurs utilisaient l'opérateur logique OR ( ||). Mais lorsque ??recherche spécifiquement nullor undefined, l' ||opérateur recherche toute valeur fausse : null, undefined, , 0, NaN, et bien sûr, false.
Dans l'exemple suivant, ala valeur de sera attribuée bsi la valeur de best vraie, sinon elle sera attribuée 3.
const a = b || 3 ;
Structures de contrôle
Énoncés composés
Une paire d'accolades { }et une séquence d'instructions fermées constituent une instruction composée, qui peut être utilisée partout où une instruction peut être utilisée.
Si ... sinon
if ( expr ) { //instructions; } else if ( expr2 ) { //instructions; } else { //instructions; }
Opérateur conditionnel (ternaire)
L'opérateur conditionnel crée une expression qui est évaluée comme l'une des deux expressions en fonction d'une condition. Cela est similaire à l' instruction if qui sélectionne l'une des deux instructions à exécuter en fonction d'une condition. En d'autres termes, l'opérateur conditionnel est aux expressions ce que l'opérateur if est aux instructions.
const résultat = condition ? expression : alternative ;
est le même que :
si ( condition ) { const résultat = expression ; } sinon { const résultat = alternative ; }
Contrairement à l' instruction if , l'opérateur conditionnel ne peut pas omettre sa « branche else ».
Déclaration de commutation
La syntaxe de l' instruction switch JavaScript est la suivante :
switch ( expr ) { case SOMEVALUE : // instructions; break ; case ANOTHERVALUE : // instructions pour quand ANOTHERVALUE || ORNAOTHERONE // pas d'instruction break, se retrouvant dans le cas suivant case ORANOTHERONE : // instructions spécifiques à ORANOTHERONE (c'est-à-dire !ANOTHERVALUE && ORANOTHER); break ; //La responsabilité s'arrête ici. case YETANOTHER : // instructions; break ; default : // instructions; break ; }
break;est facultatif ; cependant, il est généralement nécessaire, car sinon l'exécution du code continuera jusqu'au corps du bloc de cas suivant. Ce comportement de repli peut être utilisé lorsque le même ensemble d'instructions s'applique à plusieurs cas, créant ainsi une disjonction entre ces cas.- Ajoutez une instruction break à la fin du dernier cas par mesure de précaution, au cas où des cas supplémentaires seraient ajoutés ultérieurement.
- Les valeurs littérales de chaîne peuvent également être utilisées pour les valeurs de cas.
- Des expressions peuvent être utilisées à la place des valeurs.
- Le cas par défaut (facultatif) est exécuté lorsque l'expression ne correspond à aucun autre cas spécifié.
- Un appareil dentaire est obligatoire.
Boucle for
La syntaxe de la boucle JavaScript for est la suivante :
for ( initial ; condition ; instruction de boucle ) { /* les instructions seront exécutées à chaque cycle de la boucle for{}, tant que la condition est satisfaite */ }
ou
for ( initial ; condition ; instruction de boucle ( itération )) // une instruction
Pour ... en boucle
La syntaxe du JavaScript for ... in loopest la suivante :
for ( var property_name in some_object ) { // instructions utilisant some_object[property_name]; }
- Parcourt toutes les propriétés énumérables d'un objet.
- Itère sur tous les indices utilisés du tableau, y compris toutes les propriétés définies par l'utilisateur de l'objet tableau, le cas échéant. Il peut donc être préférable d'utiliser une boucle for traditionnelle avec un index numérique lors de l'itération sur les tableaux.
- Il existe des différences entre les différents navigateurs Web en ce qui concerne les propriétés qui seront reflétées avec l'instruction de boucle for...in. En théorie, cela est contrôlé par une propriété d'état interne définie par la norme ECMAscript appelée « DontEnum », mais en pratique, chaque navigateur renvoie un ensemble de propriétés légèrement différent lors de l'introspection. Il est utile de tester une propriété donnée en utilisant }. Ainsi, l'ajout d'une méthode au prototype de tableau avec } peut entraîner des boucles sur le nom de la méthode.
if(some_object.hasOwnProperty(property_name)){...Array.prototype.newMethod=function(){...for ... in
Boucle while
La syntaxe de la boucle while JavaScript est la suivante :
tandis que ( condition ) { instruction1 ; instruction2 ; instruction3 ; ... }
Faire une boucle while
La syntaxe du JavaScript do ... while loopest la suivante :
faire { instruction1 ; instruction2 ; instruction3 ; ... } while ( condition );
Avec
L'instruction with ajoute toutes les propriétés et méthodes de l'objet donné dans la portée du bloc suivant, leur permettant d'être référencées comme s'il s'agissait de variables locales.
avec ( document ) { const a = getElementById ( 'a' ); const b = getElementById ( 'b' ); const c = getElementById ( 'c' ); };
- Notez l'absence de document. avant chaque invocation de getElementById() .
La sémantique est similaire à l'instruction with de Pascal .
Étant donné que la disponibilité des instructions with entrave les performances du programme et est censée réduire la clarté du code (puisque n'importe quelle variable donnée pourrait en fait être une propriété d'un with englobant ), cette instruction n'est pas autorisée en mode strict .
Étiquettes
JavaScript prend en charge les étiquettes imbriquées dans la plupart des implémentations. Les boucles ou les blocs peuvent être étiquetés pour l'instruction break et les boucles pour continue. Bien que gotosoit un mot réservé, goto n'est pas implémenté en JavaScript.
loop1 : for ( let a = 0 ; a < 10 ; ++ a ) { if ( a === 4 ) break loop1 ; // S'arrête après la 4ème tentative console . log ( 'a = ' + a ); loop2 : for ( let b = 0 ; b < 10 ; ++ b ) { if ( b === 3 ) continue loop2 ; // Le numéro 3 est ignoré if ( b === 6 ) continue loop1 ; // Continue la première boucle, 'finished' n'est pas affiché console . log ( 'b = ' + b ); } // fin de loop2 console . log ( 'finished' ); } // fin de loop1 block1 : { console . log ( 'Hello' ); // Affiche 'Hello' break block1 ; console . log ( 'World' ); // N'arrivera jamais ici } goto block1 ; // Erreur d'analyse.
Fonctions
Une fonction est un bloc avec une liste de paramètres (éventuellement vide) à laquelle est normalement attribué un nom. Une fonction peut utiliser des variables locales. Si vous quittez la fonction sans instruction return, la valeur undefined est renvoyée.
function gcd ( number1 , number2 ) { if ( isNaN ( number1 * number2 )) throw TypeError ( " Les arguments non numériques ne sont pas autorisés." ); number1 = Math.round ( number1 ); number2 = Math.round ( number2 ) ; let difference = number1 - number2 ; if ( difference === 0 ) return number1 ; return difference > 0 ? gcd ( number2 , difference ) : gcd ( number1 , - difference ) ; } console.log ( gcd ( 60 , 40 ) ) ; // 20 //En l'absence de parenthèses suivant l'identifiant 'gcd' sur le côté droit de l'affectation ci-dessous, //'gcd' renvoie une référence à la fonction elle-même sans l'invoquer. let mygcd = gcd ; // mygcd et gcd référencent la même fonction. console . log ( mygcd ( 60 , 40 )); // 20
Les fonctions sont des objets de première classe et peuvent être affectées à d’autres variables.
Le nombre d'arguments donnés lors de l'appel d'une fonction ne correspond pas nécessairement au nombre d'arguments dans la définition de la fonction ; un argument nommé dans la définition qui n'a pas d'argument correspondant dans l'appel aura la valeur undefined (qui peut être implicitement convertie en false). Dans la fonction, les arguments sont également accessibles via l' objet arguments ; cela permet d'accéder à tous les arguments utilisant des indices (par exemple ), y compris ceux au-delà du nombre d'arguments nommés. (Bien que la liste d'arguments ait une propriété, ce n'est pas une instance de Array ; elle ne possède pas de méthodes telles que .slice() , .sort() , etc.) arguments[0],arguments[1],...arguments[n].length
fonction add7 ( x , y ) { si ( ! y ) { y = 7 ; } console.log ( x + y + arguments.length ) ; } ; add7 ( 3 ) ; // 11add7 ( 3,4 ) ; // 9
Les valeurs primitives (nombre, booléen, chaîne) sont transmises par valeur. Pour les objets, c'est la référence à l'objet qui est transmise.
const obj1 = { a : 1 }; const obj2 = { b : 2 }; function foo ( p ) { p = obj2 ; // Ignore le paramètre réel p . b = arguments [ 1 ]; } foo ( obj1 , 3 ); // N'affecte pas du tout obj1. 3 est un paramètre supplémentaire console.log ( ` $ { obj1.a } ${ obj2.b } ` ) ; // écrit 1 3
Les fonctions peuvent être déclarées à l'intérieur d'autres fonctions et accéder aux variables locales de la fonction externe. De plus, elles implémentent des fermetures complètes en mémorisant les variables locales de la fonction externe même après la fin de la fonction externe.
let t = "Top" ; let bar , baz ; function foo () { let f = "foo var" ; bar = function () { console . log ( f ) }; baz = function ( x ) { f = x ; }; } foo (); baz ( "baz arg" ); bar (); // "baz arg" (pas "foo var") même si foo() est sorti. console . log ( t ); // Top
Asynchrone/en attente
L'opérateur d'attente en JavaScript ne peut être utilisé qu'à partir d'une fonction asynchrone ou au niveau supérieur d'un module . Si le paramètre est une promesse , l'exécution de la fonction asynchrone reprendra lorsque la promesse sera résolue (à moins que la promesse ne soit rejetée, auquel cas une erreur sera générée et pourra être gérée avec la gestion normale des exceptions JavaScript ). Si le paramètre n'est pas une promesse, le paramètre lui-même sera renvoyé immédiatement.
De nombreuses bibliothèques fournissent des objets de promesse qui peuvent également être utilisés avec wait, à condition qu'ils correspondent à la spécification des promesses JavaScript natives. Cependant, les promesses de la bibliothèque jQuery n'étaient pas compatibles avec Promises/A+ avant jQuery 3.0.
Voici un exemple (modifié à partir de cet article ) :
fonction asynchrone createNewDoc () { let response = wait db . post ({}); // publier un nouveau document return db . get ( response . id ); // rechercher par identifiant } fonction asynchrone main ( ) { essayer { laisser doc = wait createNewDoc ( ); console.log ( doc ); } catch ( err ) { console.log ( err ) ; } } main ( ) ;
Objets
Pour des raisons pratiques, les types sont généralement subdivisés en primitives et objets . Les objets sont des entités qui ont une identité (elles ne sont égales qu'à elles-mêmes) et qui associent les noms de propriétés à des valeurs (« slots » dans la terminologie de la programmation basée sur des prototypes ). Les objets peuvent être considérés comme des tableaux associatifs ou des hachages, et sont souvent implémentés à l'aide de ces structures de données. Cependant, les objets ont des fonctionnalités supplémentaires, telles qu'une chaîne de prototypes , que les tableaux associatifs ordinaires n'ont pas.
JavaScript possède plusieurs types d'objets intégrés, à savoir Array, Boolean, Date, Function, Math, Number, Object, RegExpet String. D'autres objets sont des « objets hôtes », définis non pas par le langage, mais par l'environnement d'exécution. Par exemple, dans un navigateur, les objets hôtes typiques appartiennent au DOM (fenêtre, formulaire, liens, etc.).
Créer des objets
Les objets peuvent être créés à l'aide d'un constructeur ou d'un littéral d'objet. Le constructeur peut utiliser soit une fonction Object intégrée, soit une fonction personnalisée. Il est convenu que les fonctions de constructeur reçoivent un nom commençant par une majuscule :
// Constructeur const anObject = new Object (); // Objet littéral const objectA = {}; const objectA2 = {}; // A != A2, {}s crée de nouveaux objets en tant que copies. const objectB = { index1 : 'valeur 1' , index2 : 'valeur 2' }; // Constructeur personnalisé (voir ci-dessous)
Les littéraux d'objet et les littéraux de tableau permettent de créer facilement des structures de données flexibles :
const maStructure = { nom : { prénom : "Mel" , nom : "Smith" }, âge : 33 , loisirs : [ "échecs" , "jogging" ] };
C'est la base de JSON , qui est une notation simple qui utilise une syntaxe de type JavaScript pour l'échange de données.
Méthodes
Une méthode est simplement une fonction qui a été assignée à un nom de propriété d'un objet. Contrairement à de nombreux langages orientés objet, il n'y a pas de distinction entre une définition de fonction et une définition de méthode dans JavaScript lié aux objets. La distinction se produit plutôt lors de l'appel de fonction ; une fonction peut être appelée en tant que méthode.
Lorsqu'elle est appelée en tant que méthode, la variable locale standard this est simplement définie automatiquement sur l'instance d'objet à gauche du « . ». (Il existe également des méthodes call et apply qui peuvent définir this explicitement — certains packages tels que jQuery font des choses inhabituelles avec this .)
Dans l'exemple ci-dessous, Foo est utilisé comme constructeur. Un constructeur n'a rien de spécial : c'est juste une fonction simple qui initialise un objet. Lorsqu'il est utilisé avec le mot-clé new , comme c'est la norme, il est défini sur un objet vierge nouvellement créé.
Notez que dans l'exemple ci-dessous, Foo attribue simplement des valeurs à des emplacements, dont certains sont des fonctions. Il peut donc attribuer différentes fonctions à différentes instances. Il n'y a pas de prototypage dans cet exemple.
fonction px () { renvoie ceci . préfixe + "X" ; } fonction Foo ( yz ) { ceci.préfixe = " a- " ; si ( yz > 0 ) { ceci.pyz = fonction ( ) { renvoyer ceci.préfixe + " Y " ; } ; } sinon { ceci.pyz = fonction ( ) { renvoyer ceci.préfixe + " Z " ; } ; } ceci.m1 = px ; renvoyer ceci ; } const foo1 = nouveau Foo ( 1 ); const foo2 = nouveau Foo ( 0 ); foo2 . préfixe = "b-" ; console . log ( "foo1/2 " + foo1 . pyz () + foo2 . pyz ()); // foo1/2 aY bZ foo1 . m3 = px ; // Assigne la fonction elle-même, pas son résultat évalué, c'est-à-dire pas px() const baz = { "prefix" : "c-" }; baz . m4 = px ; // Pas besoin d'un constructeur pour créer un objet. console . log ( "m1/m3/m4 " + foo1 . m1 () + foo1 . m3 () + baz . m4 ()); // m1/m3/m4 aX aX cX foo1 . m2 (); // Lève une exception, car foo1.m2 n'existe pas.
Constructeurs
Les fonctions constructeurs attribuent simplement des valeurs aux emplacements d'un objet nouvellement créé. Les valeurs peuvent être des données ou d'autres fonctions.
Exemple : Manipulation d’un objet :
fonction MonObjet ( attributA , attributB ) { this . attributA = attributA ; this . attributB = attributB ; } MyObject . staticC = "blue" ; // Sur la fonction MyObject, pas sur l'objet console . log ( MyObject . staticC ); // bleu const objet = new MyObject ( 'rouge' , 1000 ); console . log ( objet . attributA ); // rouge console . log ( objet . attributB ); // 1000 console . log ( object . staticC ); // undefined object . attributeC = new Date (); // ajouter une nouvelle propriété supprimer l'objet . attributeB ; // supprimer une propriété de l'objet console . log ( objet . attributeB ); // indéfini
Le constructeur lui-même est référencé dans l' emplacement du constructeur du prototype de l'objet . Donc,
function Foo () {} // L'utilisation de 'new' définit les emplacements de prototype (par exemple, // x = new Foo() définirait le prototype de x sur Foo.prototype, // et Foo.prototype a un emplacement de constructeur pointant vers Foo). const x = new Foo (); // Ce qui précède est presque équivalent à const y = {}; y . constructor = Foo ; y . constructor (); // Sauf x . constructor == y . constructor ; // true x instanceof Foo ; // true y instanceof Foo ; // false // le prototype de y est Object.prototype, pas // Foo.prototype, puisqu'il a été initialisé avec // {} au lieu de new Foo. // Même si Foo est défini sur l'emplacement de constructeur de y, // ceci est ignoré par instanceof - seul l'emplacement de constructeur du prototype de y est pris en compte.
Les fonctions sont des objets eux-mêmes, qui peuvent être utilisés pour produire un effet similaire aux « propriétés statiques » (en utilisant la terminologie C++/Java) comme indiqué ci-dessous. (L'objet fonction possède également une prototypepropriété spéciale, comme indiqué dans la section « Héritage » ci-dessous.)
La suppression d'objet est rarement utilisée car le moteur de script récupère les objets qui ne sont plus référencés.
Héritage
JavaScript prend en charge les hiérarchies d'héritage via le prototypage à la manière de Self .
Dans l'exemple suivant, la classe Derived hérite de la classe Base . Lorsque d est créé en tant que Derived , la référence à l'instance de base de Base est copiée dans d.base .
Derive ne contient pas de valeur pour aBaseFunction , elle est donc récupérée à partir de aBaseFunction lorsque l'on accède à aBaseFunction . Cela est clarifié en modifiant la valeur de base.aBaseFunction , qui se reflète dans la valeur de d.aBaseFunction .
Certaines implémentations permettent d'accéder au prototype ou de le définir explicitement à l'aide de l' emplacement __proto__ comme indiqué ci-dessous.
fonction Base () { this.anOverride = fonction ( ) { console.log ( " Base::anOverride()" ) ; } ; ceci . aBaseFunction = function () { console . log ( "Base::aBaseFunction()" ); }; } fonction Dérivée ( ) { this.anOverride = fonction () { console.log ( " Derived::anOverride()" ) ; } ; } const base = new Base (); Derived . prototype = base ; // Doit être avant new Derived() Derived . prototype . constructor = Derived ; // Requis pour faire fonctionner `instanceof` const d = new Derived (); // Copie Derived.prototype dans l'emplacement de prototype caché de l'instance d. d instanceof Derived ; // true d instanceof Base ; // true base . aBaseFunction = function () { console . log ( "Base::aNEWBaseFunction()" ); }; d . anOverride (); // Dérivé::anOverride() d . aBaseFunction (); // Base::aNEWBaseFunction() console . log ( d . aBaseFunction == Dérivé . prototype . aBaseFunction ); // vrai console . log ( d . __proto__ == base ); // true dans les implémentations basées sur Mozilla et false dans de nombreuses autres.
Ce qui suit montre clairement comment les références aux prototypes sont copiées lors de la création d'une instance, mais que les modifications apportées à un prototype peuvent affecter toutes les instances qui y font référence.
fonction m1 () { renvoie "Un" ; } fonction m2 () { renvoie "Deux" ; } fonction m3 () { renvoie "Trois" ; } fonction Base () {} Base . prototype . m = m2 ; const bar = new Base (); console . log ( "bar.m " + bar . m ()); // bar.m Deux fonction Top () { ceci . m = m3 ; } const t = nouveau Top (); const foo = new Base (); Base . prototype = t ; // Aucun effet sur foo, la *référence* à t est copiée. console . log ( "foo.m " + foo . m ()); // foo.m Deux const baz = new Base (); console.log ( " baz.m " + baz.m ()) ; // baz.m Trois t . m = m1 ; // Affecte baz et toutes les autres classes dérivées. console . log ( "baz.m1 " + baz . m ()); // baz.m1 One
Dans la pratique, de nombreuses variantes de ces thèmes sont utilisées, et cela peut être à la fois puissant et déroutant.
Gestion des exceptions
JavaScript inclut une instruction try ... catch ... finally
de gestion des exceptions pour gérer les erreurs d'exécution.
L' try ... catch ... finallyinstruction intercepte les exceptions résultant d'une erreur ou d'une instruction throw. Sa syntaxe est la suivante :
try { // Instructions dans lesquelles des exceptions peuvent être levées } catch ( errorValue ) { // Instructions qui s'exécutent en cas d'exception } finally { // Instructions qui s'exécutent ensuite dans un sens ou dans l'autre }
Au départ, les instructions du bloc try s'exécutent. Si une exception est levée, le flux de contrôle du script est immédiatement transféré vers les instructions du bloc catch, l'exception étant disponible comme argument d'erreur. Sinon, le bloc catch est ignoré. Le bloc catch peut throw(errorValue) s'il ne souhaite pas gérer une erreur spécifique.
Dans tous les cas, les instructions du bloc finally sont toujours exécutées. Cela peut être utilisé pour libérer des ressources, bien que la mémoire soit automatiquement récupérée.
La clause catch ou finally peut être omise. L'argument catch est obligatoire.
L'implémentation de Mozilla permet d'utiliser plusieurs instructions catch, en tant qu'extension de la norme ECMAScript. Elles suivent une syntaxe similaire à celle utilisée en Java :
essayer { instruction ; } catch ( e si e == "InvalidNameException" ) { instruction ; } catch ( e si e == "InvalidIdException" ) { instruction ; } catch ( e si e == "InvalidEmailException" ) { instruction ; } catch ( e ) { instruction ; }
Dans un navigateur, l' événement onerror est plus couramment utilisé pour intercepter les exceptions.
onerror = fonction ( valeurerreur , url , numéroligne ) {...; renvoie vrai ;};
Fonctions et méthodes natives
évaluer (expression)
Evaluates the first parameter as an expression, which can include assignment statements. Variables local to functions can be referenced by the expression. However, eval represents a major security risk, as it allows a bad actor to execute arbitrary code, so its use is discouraged.
>(functionfoo(){ ...varx=7; ...console.log("val "+eval("x + 2")); ...})(); val9 undefined