Grammaire lexicale

Cette page décrit la grammaire lexicale de JavaScript. Le code source d'un script ECMAScript est analysé de gauche à droite et est converti en une série d'éléments qui sont : des jetons, des caractères de contrôle, des terminateurs de lignes, des commentaires ou des blancs. ECMAScript définit également certains mots-clés et littéraux. ECMAScript possède également des règles pour insérer automatiquement des points-virgules à la fin des instructions.

Caractères de contrôle

Les caractères de contrôle n'ont aucune représentation visuelle mais sont utilisés pour contrôler l'interprétation du texte.

Caractères de contrôle au format Unicode
Point de code Nom Abréviation Description
U+200C Antiliant sans chasse (zero width non-joiner en anglais) <ZWNJ> Placé entre des caractères pour empêcher qu'ils soient connectés par une ligature dans certaines langues (Wikipédia).
U+200D Liant sans chasse (zero width joiner en anglais) <ZWJ> Placé entre des caractères qui ne seraient normalement pas connectés pour les afficher comme connectés dans certaines langues (Wikipédia).
U+FEFF Indicateur d'ordre des octets (byte order mark en anglais) <BOM> Utilisé au début d'un script pour indiquer qu'il est en Unicode et quel est l'ordre des octets (Wikipedia).

Blancs

Les caractères d'espacement (blancs) sont utilisés pour des raisons de lisibilité et permetttent de séparer les différents fragments entre eux. Ces caractères sont généralement inutiles au code. Les outils de minification sont souvent utilisés pour retirer les blancs afin de réduire le volume de données à transférer.

Caractères d'espacament
Point de code Nom Abréviation Description Séquence d'échappement
U+0009 Tabulation (horizontale) <HT> Tabulation horizontale \t
U+000B Tabulation verticale <VT> Tabulation verticale \v
U+000C Caractère de saut de page (form feed en anglais) <FF> Caractère de contrôle pour le saut de page (Wikipédia). \f
U+0020 Espace sécable (space en anglais) <SP> Espace sécable  
U+00A0 Espace insécable (no-break space en anglais) <NBSP> Espace insécable  
Others Autres caractères d'espaces Unicode <USP> Espaces Unicode sur Wikipédia  

Terminateurs de lignes

En plus des blancs, les caractères de fin de ligne (terminateurs de lignes) sont utilisés pour améliorer la lisibilité du texte. Cependant, dans certains cas, les terminateurs de lignes peuvent influencer l'exécution du code JavaScript là où ils sont interdits. Les terminateurs de lignes affectent également le processus d'insertion automatique des points-virgules. Les terminateurs de lignes correspondent à la classe \s des expressions rationnelles.

Seuls les points de code Unicode qui suivent sont traités comme des fins de lignes en ECMAScript, les autres caractères sont traités comme des blancs (par exemple : Next Line (nouvelle ligne) : NEL, U+0085 est considéré comme un blanc).

Caractères de fin de ligne
Point de code Nom Abréviation Description Séquence d'échappement
U+000A Nouvelle ligne <LF> Caractère de nouvelle ligne pour les systèmes UNIX. \n
U+000D Retour chariot <CR> Caractère de nouvelle ligne pour les systèmes Commodore et les premiers Mac. \r
U+2028 Séparateur de ligne <LS> Wikipédia  
U+2029 Séparateur de paragraphe <PS> Wikipédia  

Commentaires

Les commentaires sont utilisés pour fournir des notes, des suggestions, des indications ou des avertissements sur le code JavaScript. Cela peut en faciliter la lecture et la compréhension. Ils peuvent également être utilisés pour empêcher l'exécution d'un certain code ; cela peut être pratique lors du débogage.

En JavaScript, Il existe deux façons de former des commentaires :

La première façon est d'utiliser // (double barre oblique), pour commenter tout le texte qui suit (sur la même ligne). Par exemple :

function comment() {
  // Voici un commentaire d'une ligne en JavaScript
  console.log("Hello world !");
}
comment();

La seconde façon est d'utiliser /* */, qui est plus flexible.

Il est possible d'utiliser cette forme sur une seule ligne :

function comment() {
  /* Voici un commentaire d'une ligne en JavaScript */
  console.log("Hello world !");
}
comment();

Mais également sur plusieurs lignes, comme ceci :

function comment() {
  /* Ce commentaire s'étend sur plusieurs lignes. Il n'y a
     pas besoin de clore le commentaire avant d'avoir
     fini. */
  console.log("Hello world !");
}
comment();

Il est également possible d'utiliser un commentaire au milieu d'une ligne. En revanche, cela rend le code plus difficile à lire et devrait être utilisé avec attention :

function comment(x) {
  console.log("Hello " + x /* insérer la valeur de x */ + " !");
}
comment("world");

On peut également encadrer du code pour l'empêcher d'être exécuté. Par exemple :

function comment() {
  /* console.log("Hello world !"); */
}
comment();

Ici, l'appel console.log() n'a jamais lieu car il fait partie d'un commentaire. On peut ainsi désactiver plusieurs lignes de code d'un coup.

Mots-clés

Mots-clés réservés selon ECMAScript 6

Mots-clés réservés pour le futur

Les mots-clés qui suivent ont été réservés pour une utilisation future dans la spécification ECMAScript. Ils n'ont actuellement aucune utilité mais pourrait être utilisés par la suite. Ils ne peuvent donc pas être utilisés comme identifiants. Ces mots-clés ne peuvent être utilisés ni en mode strict ni en mode non strict.

  • enum
  • await (lorsqu'il est utilisé dans le contexte d'un module)

Les mots-clés suivants sont réservés dans du code en mode strict :

  • implements
  • let
  • package
  • protected
  • static
  • interface
  • private
  • public

Mots-clés réservés pour un usage future dans les anciens standards

Les mots-clés suivants sont réservés dans les anciennes spécifications ECMAScript (ECMAScript 1 à 3).

  • abstract
  • boolean
  • byte
  • char
  • double
  • final
  • float
  • goto
  • int
  • long
  • native
  • short
  • synchronized
  • throws
  • transient
  • volatile

Par ailleurs, les littéraux null, true, et false sont réservés dans ECMAScript pour leur usage normal.

Utilisation des mots-clés réservés

Les mots-clés réservés ne le sont que pour les identifiants (et non pour les IdentifierNames) . Comme décrit dans es5.github.com/#A.1, dans l'exemple qui suit, on a, légalement, des IdentifierNames qui utilisent des ReservedWords.

a.import
a["import"]
a = { import: "test" }.

En revanche, dans ce qui suit, c'est illégal car c'est un identifiant. Un identifiant peut être un IdentifierName mais pas un mot-clé réservé. Les identifiants sont utilisés pour les  FunctionDeclaration (déclarations de fonction) et les FunctionExpression (expressions de fonction).

function import() {} // Illégal.

Littéraux

Littéral null

Voir aussi la page null pour plus d'informations.

null

Littéraux booléens

Voir aussi la page Boolean pour plus d'informations.

true
false

Littéraux numériques

Décimaux

1234567890
42

// Attention à l'utilisation de zéros en début :

0888 // 888 est compris comme décimal
0777 // est compris comme octal et égale 511 en décimal

Les littéraux décimaux peuvent commencer par un zéro (0) suivi d'un autre chiffre. Mais si tous les chiffres après le 0 sont (strictement) inférieurs à 8, le nombre sera analysé comme un nombre octal. Cela n'entraînera pas d'erreur JavaScript, voir bug 957513. Voir aussi la page sur parseInt().

Binaires

La représentation binaire des nombres peut être utilisée avec une syntaxe qui comporte un zéro (0) suivi par le caractère latin "B" (minuscule ou majuscule) (0b ou 0B). Cette syntaxe est apparue avec ECMAScript 6 et il faut donc faire attention au tableau de compatibilité pour cette fonctionnalité. Si les chiffres qui composent le nombre ne sont pas 0 ou 1, cela entraînera une erreur SyntaxError : "Missing binary digits after 0b".

var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607

Octaux

La syntaxe pour représenter des nombres sous forme octale est : un zéro (0), suivi par la lettre latine "O" (minuscule ou majuscule) (ce qui donne 0o ou 0O). Cette syntaxe est apparue avec ECMAScript 6 et il faut donc faire attention au tableau de compatibilité pour cette fonctionnalité. Si les chiffres qui composent le nombre ne sont pas compris entre 0 et 7, cela entraînera une erreur SyntaxError : "Missing octal digits after 0o".

var n = 0O755; // 493
var m = 0o644; // 420

// Aussi possible en utilisant des zéros en début du nombre (voir la note ci-avant)
0755
0644

Hexadécimaux

Les littéraux hexadécimaux ont pour syntaxe : un zéro (0), suivi par la lettre latine "X" (minuscule ou majuscule) (ce qui donne 0x ou 0X). Si les chiffres qui composent le nombre sont en dehors des unités hexadécimales (0123456789ABCDEF), cela entraînera une erreur SyntaxError : "Identifier starts immediately after numeric literal".

0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF   // 81985529216486900
0XA                 // 10

Littéraux objets

Voir aussi les pages Object et Initialisateur d'objet pour plus d'informations.

var o = { a: "toto", b: "truc", c: 42 };

// notation raccourcie depuis ES6
var a = "toto", b = "truc", c = 42;
var o = {a, b, c};
// plutôt que
var o = { a: a, b: b, c: c };

Littéraux de tableaux

Voir aussi la page Array pour plus d'informations.

[1954, 1974, 1990, 2014]

Littéraux de chaînes de caractères

'toto'
"truc"

Séquence d'échappement hexadécimale

'\xA9' // "©"

Séquence d'échappement Unicode

La séquence d'échappement Unicode est composée de \u suivi d'au moins quatres caractères.

'\u00A9' // "©"

Échappement de points de code Unicode

Apparu avec ECMAScript 6, l'échappement de points de code Unicode permet d'échapper n'importe quel caractère en utilisant une notation hexadécimale. Il est possible de le faire pour échapper les points de code Unicode dont la représentation va jusqu'à 0x10FFFF. Avec la séquence « simple » d'échappement Unicode, il était nécessaire d'échapper respectivement les deux demi-codets d'une paire si on voulait échapper le caractère correspondant, avec cette nouvelle méthode, ce n'est plus nécessaire de faire la distinction.

Voir également String.fromCodePoint() et String.prototype.codePointAt().

'\u{2F804}'

// avec l'ancienne méthode d'échappement, cela aurait été écrit
'\uD87E\uDC04'

Littéraux d'expressions rationnelles

Voir la page RegExp pour plus d'informations.

/ab+c/g

// Un littéral pour une expression rationnelle 
// vide. Le groupe non-capturant est utilisé pour
// lever l'ambigüité avec les commentaires 
/(?:)/

 

Littéraux modèles (gabarits ou templates)

Voir également la page sur les gabarits de chaînes de caractères pour plus d'informations.

`chaîne de caractères`

`chaîne de caractères ligne 1
 chaîne de caractères ligne 2`

`chaîne1 ${expression} chaîne2`

tag `chaîne1 ${expression} chaîne2`

Insertion automatique de points-virgules

Certaines instructions JavaScript doivent finir par un point-virgule et sont donc concernées par l'insertion automatique de points-virgules (ASI pour automatic semicolon insertion en anglais) :

  • Instruction vide
  • instruction de variable, let, const
  • import, export, déclaration de module
  • Instruction d'expression
  • debugger
  • continue, break, throw
  • return

La spécification ECMAScript mentionne trois règles quant à l'insertion de points-virgules :

1. Un point-vrigule est inséré avant un terminateur de ligne ou une accolade ("}") quand celui ou celle-ci n'est pas autorisé par la grammaire

{ 1 2 } 3
// est donc transformé, après ASI, en :
{ 1 2 ;} 3;

2. Un point-virgule est inséré à la fin lorsqu'on détecte la fin d'une série de jetons en flux d'entrée et que le parseur est incapable d'analyser le flux d'entrée comme un programme complet.

Ici ++ n'est pas traité comme opérateur postfixe s'appliquant à la variable b car il y a un terminateur de ligne entre b et ++.

a = b
++c

// devient, après ASI : 

a = b;
++c;

3. Un point-virgule est inséré à la fin, lorsqu'une instruction, à production limitée pour la grammaire, est suivie par un terminateur de ligne. Les instructions concernées par cette règle sont :

  • Expressions postfixes (++ et --)
  • continue
  • break
  • return
  • yield, yield*
  • module
return
a + b

// est transformé, après ASI, en :

return;
a + b;

Spécifications

Spécification Statut Commentaires
ECMAScript 1st Edition (ECMA-262) Standard Définition initiale.
ECMAScript 5.1 (ECMA-262)
La définition de 'Lexical Conventions' dans cette spécification.
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
La définition de 'Lexical Grammar' dans cette spécification.
Standard Ajout : littéraux binaires et octaux, échappements de points de code Unicode, modèles
ECMAScript 2017 Draft (ECMA-262)
La définition de 'Lexical Grammar' dans cette spécification.
Projet  

Compatibilité des navigateurs

Fonctionnalité Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Support simple (Oui) (Oui) (Oui) (Oui) (Oui) (Oui)
Littéraux numériques binaires et octaux
(0b et 0o)
41 12 25 (25) ? 28 ?
Échappements de points de code Unicode
(\u{})
? 12 Pas de support
bug 320500
? ? ?
Notation raccourcie pour les littéraux objets Pas de support 12 33 (33) Pas de support Pas de support Pas de support
Littéraux modèles Pas de support 12 34 (34) Pas de support Pas de support Pas de support
Fonctionnalité Android Chrome pour Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Support simple (Oui) (Oui) (Oui) (Oui) (Oui) (Oui)
Littéraux numériques binaires et octaux ? 41 33.0 (33) ? ? ?
Échappements de points de code Unicode ? ? Pas de support
bug 320500
? ? ?
Notation raccourcie pour les littéraux objets Pas de support Pas de support 33.0 (33) Pas de support Pas de support Pas de support
Littéraux modèles Pas de support Pas de support 34.0 (34) Pas de support Pas de support Pas de support

Notes spécifiques à Firefox

  • Pour les versions antérieures à Firefox 5 (JavaScript 1.8.6), les mots-clés réservés pour le futur pouvaient être utilisés en dehors du mode strict. Cette erreur par rapport à ECMAScript a été réparée Firefox 5.

Voir aussi

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : SphinxKnight
 Dernière mise à jour par : SphinxKnight,