Les modèles de libellés sont des libellés de chaînes de caractères permettant d'intégrer des expressions. Avec eux, vous pouvez utiliser des chaînes de caractères multi-lignes ainsi que des fonctionnalités d'interpolation de ces chaînes.

Syntaxe

`texte`

`ligne de texte 1
 ligne de texte 2`

`texte ${expression} texte`

etiquette `texte ${expression} texte`

Description

Les modèles de libellés sont délimités par des caractères accent grave (` `)  au lieu des apostrophes doubles ou simples. Les modèles de libellés peuvent contenir des espaces réservés. Ils sont indiqués par le sine dollar ($) et des accolades (${expression}). Les expressions dans les espaces réservés et le texte compris dans ces espaces sont passés à une fonction. La fonction par défaut concatène simplement les différentes parties en une seule chaîne. Si une expression précède le modèle de libellé (ici etiquette), le modèle de libellé est appelée "modèle de libellé balisé". Dans ce cas, l'expression balisée (habituellement une fonction)  est appelée avec le modèle de libellé traité, que vous pouvez alors manipuler avant envoi. Pour sortir des accents graves dans un modèle de libellé, mettez une barre oblique inverse  (\) avant l'accent grave :

`\`` === "`"; // true

Les chaînes de caractères multi-lignes

Tous les caractères de saut de ligne insérés dans la source font partie du modèle de libellé. Avec des chaînes de caractères normales, il vous aurait fallu utiliser la syntaxe suivante pour obtenir des chaînes multi-lignes :

console.log('ligne de texte 1\n'+
'ligne de texte 2');
// "ligne de texte 1
// ligne de texte 2"

Pour obtenir le même effet avec les gabarits, vous pouvez maintenant écrire :

console.log(`ligne de texte 1
ligne de texte 2`);
// "ligne de texte 1
//  ligne de texte 2"

Interpolation d'expressions

Pour intégrer des expressions dans des chaînes de caractères normales, il vous fallait utiliser la syntaxe suivante :

var a = 5;
var b = 10;
console.log('Quinze vaut ' + (a + b) + ' et\non ' + (2 * a + b) + '.');
// "Quinze vaut 15 et
// non 20."

Maintenant, avec les modèles de libellés, vous pouvez faire usage de sucre syntaxique rendant plus lisibles les substitutions comme celle-ci :

var a = 5;
var b = 10;
console.log(`Quinze vaut ${a + b}
et non ${2 * a + b}.`);
// "Quinze vaut 15 et
// non 20."

Imbrication de modèles

Parfois, l'imbrication d'un modèle est la façon la plus facile et peut-être la plus lisible d'avoir des chaînes de caractères configurables. À l'intérieur d'un modèle à accents graves, il est simple d'avoir des accents graves internes, simplement en les utilisant à l'intérieur d'un espace réservé à l'intérieur du modèle.

En ES5 :

var classes = 'header'
classes += (isLargeScreen() ?
   '' : item.isCollapsed ?
     ' icon-expander' : ' icon-collapser');

En ES2015 avec des littéraux de modèle et sans imbrication :

const classes = `header ${ isLargeScreen() ? '' :
    (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;

En ES2015 avec des littéraux de modèle imbriqués :

const classes = `header ${ isLargeScreen() ? '' :
 `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;

Modèles étiquetés

Une forme plus avancée de modèles de libellés est constituée par les modèles balisés. Les balises vous permettent de faire analyser les modèles de libellés par une fonction. Le premier argument d'une fonction balise contient un ensemble de valeurs issues de chaînes de caractères. Les arguments restants concernent les expressions. Au final, votre fonction peut avoir comme résultat votre chaîne remaniée (ou elle peut afficher quelque chose de complètement différent, comme décrit dans l'exemple suivant). Le nom de la fonction utilisée pour la balise peut être tout nom que vous souhaitez.

var personne = 'Michou';
var age = 28;

function monEtiquette(chaines, expPersonne, expAge) {

  var chn0 = chaines[0]; // "ce "
  var chn1 = chaines[1]; // " est un "

  // Techniquement, il y a une chaîne après
  // l'expression finale (dans notre exemple),
  // mais elle est vide (""), donc ne pas en tenir compte.
  // var chn2 = chaines[2];

  var chnAge;
  if (expAge > 99){
    chnAge = 'centenaire';
  } else {
    chnAge = 'jeunot';
  }
  // On peut tout à fait renvoyer une chaîne construite
  // avec un gabarit
  return `${chn0}${expPersonne}${chn1}${chnAge}`;
}

var sortie = monEtiquette`ce ${ personne } est un ${ age }`;

console.log(sortie);
// ce Michou est un jeunot

Les fonctions de balises ne renvoient pas nécessairement une chaîne, comme montré dans l'exemple suivant :

function modele(chaines, ...cles) {
  return (function(...valeurs) {
    var dict = valeurs[valeurs.length - 1] || {};
    var resultat = [chaines[0]];
    cles.forEach(function(cle, i) {
      var valeur = Number.isInteger(cle) ? valeurs[cle] : dict[cle];
      resultat.push(valeur, chaines[i + 1]);
    });
    return resultat.join('');
  });
}

var t1Fin = modele`${0}${1}${0}!`;
t1Fin('C', 'HI');  // "CHIC!"
var t2Fin = modele`${0} ${'truc'}!`;
t2Fin('Hello', {truc: 'World'});  // "Hello World!"

Chaînes brutes

La propriété spéciale raw, disponible sur le premier argument  de la fonction du modèle balisé vous permet d'accéder aux chaînes brutes, telles qu'elles ont été entrées, sans traiter les séquences d'échappement.

function etiquette(chaines) {
  console.log(chaines.raw[0]);
}

etiquette`ligne de texte 1 \n ligne de texte 2`;
// affichera dans la console : 
// "ligne de texte 1 \n ligne de texte 2"

En outre, la méthode String.raw() a pour fonction de créer des chaînes de caractères brutes, exactement comme la fonction de modèle et de concaténation de chaînes par défaut le ferait :

var chn = String.raw`Salut\n${2+3}!`; 
// "Salut\n5!"

chn.length;
// 9

chn.split('').join(',');
// "S,a,l,u,t,\,n,5,!"

Les modèles étiquetés et les séquences d'échappement

Comportement de ES2016

Quant à ECMAScript 2016, les modèles étiquetés se conforment aux règles de séquences d'échappement suivantes :

  • Les séquences d'échappement Unicode commencent par "\u", par exemple\u00A9
  • Les séquences d'échappement pour les points de code Unicode sont indiquées par "\u{}", par exemple \u{2F804}
  • Les séquences d'échappement hexadécimales commencent par "\x", par exemple \xA9
  • Les séquences d'échappement octales commencent par "\" et un (plusieurs) chiffre(s), par exemple \251.

Cela signifie qu'un modèle étiqueté comme celui qui suit pose problème du fait que, selon la grammaire ECMAScript, un analyseur recherchera des séquences d'échappement Unicode valides, mais trouvera la syntaxe mal formée :

latex`\unicode`
// Génère, dans les anciennes versions ECMAScript (ES2016 et précédentes)
// SyntaxError: malformed Unicode character escape sequence

Révision ES2018 pour les séquences d'échappement illégales

Les modèles étiquetés doivent permettre l'intégration d'autres langages (par exemple, des DSL ou du LaTeX), dans lesquels d'autres séquences d'échappement sont fréquentes. La proposition Template Literal Revision pour ECMAScript (étape 4, à intégrer dans le standard ECMAScript 2018) supprime la restriction syntaxique des séquences d'échappement dans les modèles étiquetés.

Toutefois, les séquences d'échappement illégales doivent toujours être représentées dans la version "bidouillée". Elles seront affichées comme un élément undefined dans le tableau "bidouillé" :

function latex(chn) { 
 return { "bidouillee": chn[0], "brute": chn.raw[0] }
} 

latex`\unicode`

// { bidouillee: undefined, brute: "\\unicode" }

Notez que la restriction sur les séquences d'échappement est uniquement supprimée pour les modèles étiquetés, et non pour les modèles de libellés non étiquetés :

let mauvaise = `mauvaise séquence d'échappement : \unicode`;

Spécifications

Spécification État Commentaires
ECMAScript 2015 (6th Edition, ECMA-262)
La définition de 'Template Literals' dans cette spécification.
Standard Définition initiale. Définie dans plusieurs sections de la spécification : Template Literals, Tagged Templates
ECMAScript Latest Draft (ECMA-262)
La définition de 'Template Literals' dans cette spécification.
Projet Définie dans plusieurs sections de la spécification : Template Literals, Tagged Templates

Compatibilité des navigateurs

FonctionnalitéChromeEdgeFirefoxInternet ExplorerOperaSafari
Support simple411234 Non289
Escape sequences allowed in tagged template literals Non Non53 Non Non Non
FonctionnalitéAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Support simple4141123428 ?4.0
Escape sequences allowed in tagged template literals Non Non Non53 Non Non Non

Voir aussi

Étiquettes et contributeurs liés au document

Étiquettes : 
Dernière mise à jour par : SphinxKnight,