Un chemin pour comprendre les littéraux de modèle en JavaScript

La spécification ECMAScript, publiée en 2015 ( ES6 ), a ajouté une nouvelle fonctionnalité à JavaScript: les littéraux de modèle. Les littéraux de modèle nous donnent un nouveau mécanisme pour créer des valeurs de chaîne... Ce mécanisme présente de nombreuses fonctionnalités puissantes, telles que la création de constructions multilignes et l'utilisation d'espaces réservés pour incorporer des résultats d'expression dans des chaînes. De plus, il y a une autre possibilité ici - les littéraux de gabarit étiquetés. Il s'agit d'une forme étendue de littéraux de modèle. Les modèles de balises vous permettent de créer des chaînes en utilisant des expressions à l'intérieur de chaînes et en utilisant des fonctions spéciales. Tout cela élargit la capacité des programmeurs à travailler avec des chaînes, permettant, par exemple, de créer des chaînes dynamiques qui peuvent être des URL , ou d'écrire des fonctions pour affiner les éléments HTML .







Dans cet article, vous découvrirez les différences entre les valeurs de chaîne régulières, spécifiées avec des guillemets simples ou doubles, et les littéraux de modèle. Vous découvrirez différentes manières de déclarer des chaînes avec des caractéristiques différentes, y compris des chaînes multilignes et des chaînes dynamiques qui changent en fonction de la valeur d'une variable ou d'une expression. Vous apprendrez à travailler avec des modèles de balises et découvrirez des exemples concrets de leur utilisation.



Déclaration de chaînes



Dans cette section, nous rappelons comment les chaînes sont déclarées à l'aide de guillemets simples ou doubles, puis examinons comment la même chose est faite lors de l'utilisation de littéraux de modèle.



Une chaîne JavaScript peut être considérée comme une séquence de caractères entre guillemets simples ( ' '):



const single = 'Every day is a good day when you paint.'


Une autre façon de déclarer des chaînes est d'utiliser des guillemets doubles ( " "):



const double = "Be so very light. Be a gentle whisper."


En JavaScript, il n'y a pas de différences majeures entre ces chaînes. Dans d'autres langues, l'utilisation de guillemets différents lors de la déclaration de chaînes peut signifier, par exemple, que les chaînes d'un type peuvent être interpolées tandis que d'autres ne le peuvent pas. Ici, nous entendons par «interpolation» la capacité de calculer les valeurs des expressions d'espace réservé qui agissent comme des parties dynamiques de chaînes et contribuent à la formation des valeurs de chaîne résultantes.



Les chaînes à utiliser lorsqu'elles sont déclarées avec des guillemets simples ou doubles sont en grande partie une question de préférence personnelle et de conventions de codage. Toutefois, si le même type de guillemets apparaît dans une chaîne délimitée par l'un de ces types de guillemets, ils doivent être échappés . Les guillemets d'un autre type dans de telles chaînes n'ont pas besoin d'être échappés.



//     ,   
const single = '"We don\'t make mistakes. We just have happy accidents." - Bob Ross'

//     ,   
const double = "\"We don't make mistakes. We just have happy accidents.\" - Bob Ross"

console.log(single);
console.log(double);


L'appel d'une paire de méthodes log()entraînera l' envoi de deux lignes identiques à la console .



"We don't make mistakes. We just have happy accidents." - Bob Ross
"We don't make mistakes. We just have happy accidents." - Bob Ross


Les littéraux de modèle, en revanche, sont déclarés en utilisant des backticks ( ` `):



const template = `Find freedom on this canvas.`


Il n'est pas nécessaire d'échapper aux guillemets simples ou doubles ici:



const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross


Mais les backticks dans de telles chaînes doivent être échappés:



const template = `Template literals use the \` character.`


Les littéraux de modèle ont toutes les capacités des chaînes régulières. Par conséquent, vous pouvez probablement remplacer toutes les chaînes de votre projet par des modèles littéraux sans rien perdre. Le plus souvent, cependant, les conventions de codage spécifient que les littéraux de modèle ne doivent être utilisés que lorsque leurs capacités spéciales sont nécessaires. Les chaînes ordinaires sont toujours déclarées en utilisant des guillemets simples ou doubles pour maintenir la cohérence du code. La base de code du projet, lors de l'écriture qui suit ce standard, sera plus facile à lire pour les développeurs qui ne la connaissaient pas auparavant.



Maintenant que nous avons parlé de déclarer des chaînes en utilisant des guillemets simples, des guillemets doubles et des guillemets inversés, nous pouvons passer à l'examen de la première force des littéraux de modèle. À savoir - à la possibilité de décrire des chaînes multilignes.



Chaînes multilignes



Dans cette section, nous allons d'abord parler de la façon dont les chaînes multilignes ont été déclarées avant ES6, puis nous verrons comment les littéraux de modèle simplifient cette tâche.



Au départ, si vous deviez saisir une variable chaîne composée de plusieurs lignes dans un éditeur de texte, l' opérateur de concaténation de chaîne était utilisé . L'exemple de concaténation de chaînes suivant illustre cette idée:



const address =
  'Homer J. Simpson' +
  '742 Evergreen Terrace' +
  'Springfield'


Cette approche peut vous permettre de diviser les longues lignes en petits morceaux et de les organiser dans un éditeur de texte sur plusieurs lignes. Mais cela n'affecte en aucun cas le résultat de la dernière rangée. Dans ce cas, la valeur de la constante de chaîne sera située sur une ligne. Les parties à partir desquelles la valeur de chaîne est assemblée ne seront pas séparées par des sauts de ligne ou des espaces. Si vous imprimez une constante sur la console address, ce qui suit apparaîtra ici:



Homer J. Simpson742 Evergreen TerraceSpringfield


Une autre approche pour écrire de telles lignes dans les éditeurs de code consiste à utiliser la barre oblique inverse ( \), qui est placée à la fin des fragments de ligne, et après laquelle, sur une nouvelle ligne, de nouveaux fragments sont localisés:



const address =
  'Homer J. Simpson\
  742 Evergreen Terrace\
  Springfield'


Cette approche préserve, par exemple, les espaces avant les fragments de ligne, mais la valeur de la variable, si elle est imprimée sur la console, sera à nouveau représentée par une seule ligne:



Homer J. Simpson  742 Evergreen Terrace  Springfield


Vous pouvez créer une véritable chaîne multiligne en utilisant le caractère de saut de ligne ( \n):



const address =
  'Homer J. Simpson\n' +
  '742 Evergreen Terrace\n' +
  'Springfield'


Lors de l'affichage d'une valeur de chaîne stockée dans la console address, cette valeur s'étendra sur plusieurs lignes:



Homer J. Simpson
742 Evergreen Terrace
Springfield


Cependant, l'utilisation du caractère de nouvelle ligne pour créer des chaînes multilignes n'est pas particulièrement pratique et facile. D'un autre côté, la création de chaînes multilignes à l'aide de littéraux de modèle est beaucoup plus facile et plus pratique. Pas besoin de concaténer les chaînes, pas besoin d'utiliser une nouvelle ligne ou une barre oblique inverse. Pour créer des chaînes multilignes à l'aide de littéraux de modèle, c'est assez simple, à la fin du fragment suivant d'une ligne, appuyez sur la touche Enteret continuez à entrer la ligne suivante du littéral de modèle:



const address = `Homer J. Simpson
742 Evergreen Terrace
Springfield`


Si vous sortez cette constante dans la console, le texte aura le même aspect que dans l'éditeur:



Homer J. Simpson
742 Evergreen Terrace
Springfield


Ici, il convient de garder à l'esprit que s'il y a des espaces entre les backticks qui sont utilisés pour aligner le code, ces espaces seront inclus dans le littéral du modèle final. Prenons l'exemple suivant:



const address = `Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield`


Bien que ce style de codage facilite la lecture, ce qui arrive à la console après sa sortie ne sera pas très attrayant:



Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield


Maintenant, après avoir traité des chaînes multilignes, parlons de la façon dont vous pouvez intégrer les résultats de l'évaluation de diverses expressions dans des chaînes déclarées de différentes manières, c'est-à-dire parlons d'interpolation d'expressions.



Interpolation d'expression



Auparavant, avant ES6, la concaténation était utilisée pour créer des chaînes dynamiques qui impliquaient des valeurs de variable ou d'expression:



const method = 'concatenation'
const dynamicString = 'This string is using ' + method + '.'


Si vous dynamicStringsortez sur la console, vous obtenez ce qui suit:



This string is using concatenation.


Lors de l'utilisation de littéraux de modèle, les expressions peuvent être incorporées dans la chaîne à l'aide d'espaces réservés. Un espace réservé est une conception de vue ${}. Dans ce cas, tout ce qui est contenu entre accolades est considéré comme du code JavaScript, et tout ce qui est en dehors de cette construction est considéré comme une chaîne:



const method = 'interpolation'
const dynamicString = `This string is using ${method}.`


Lors de la sortie dynamicStringvers la console, vous obtenez le résultat suivant:



This string is using interpolation.


Un exemple courant d'incorporation de valeurs dans des chaînes est la création d'URL dynamiques. L'utilisation de la concaténation à cet effet conduit à l'apparition de constructions encombrantes et peu pratiques. Par exemple, voici une fonction qui génère une chaîne d'accès OAuth :



function createOAuthString(host, clientId, scope) {
  return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=' + scope
}

createOAuthString('https://github.com', 'abc123', 'repo,user')


Si vous imprimez le résultat de cette fonction sur la console, vous obtenez ce qui suit:



https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user


Lors de l'utilisation de l'interpolation, les programmeurs n'ont plus besoin de faire attention aux guillemets qui délimitent des parties de la chaîne et où se trouve l'opérateur de concaténation. Voici le même exemple, réécrit à l'aide de littéraux de modèle:



function createOAuthString(host, clientId, scope) {
  return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}`
}

createOAuthString('https://github.com', 'abc123', 'repo,user')


Le résultat de la fonction sera le suivant:



https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user


Vous pouvez utiliser la méthode trim () pour supprimer les espaces de début et de fin d'une chaîne créée avec un littéral de modèle . Par exemple, dans l'extrait de code suivant pour créer un élément HTMLavec une référence personnalisée, une fonction flèche est utilisée :



const menuItem = (url, link) =>
  `
<li>
  <a href="${url}">${link}</a>
</li>
`.trim()

menuItem('https://google.com', 'Google')


Les espaces de début et de fin seront supprimés de la dernière ligne pour garantir que l'élément est correctement rendu:



<li>
  <a href="https://google.com">Google</a>
</li>


Des expressions entières peuvent être interpolées, pas seulement des variables. Par exemple - comme ici, où le résultat de l'ajout de deux nombres est incorporé dans une chaîne:



const sum = (x, y) => x + y
const x = 5
const y = 100
const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`

console.log(string)


Ici, la fonction sum()et les constantes sont déclarées xet y. Après cela, la ligne utilise à la fois la fonction et ces constantes. Voici à quoi ressemble la constante stringlorsqu'elle est imprimée sur la console:



The sum of 5 and 100 is 105.


Ce mécanisme peut être particulièrement utile lors de l'utilisation de l' opérateur ternaire , qui vous permet de vérifier les conditions lors de la formation d'une chaîne:



const age = 19
const message = `You can ${age < 21 ? 'not' : ''} view this page`
console.log(message)


La constante messageimprimée sur la console peut changer, selon qu'elle est supérieure ou inférieure à 21, la valeur stockée dans age. Puisque cette valeur est 19 dans notre exemple, ce qui suit sera envoyé à la console:



You can not view this page


Vous savez maintenant comment vous pouvez bénéficier de l'interpolation d'expression lors de l'utilisation de littéraux de modèle. Dans la section suivante, nous irons plus loin et explorerons les modèles de balisage, et parlerons de l'utilisation d'expressions passées dans des étendues qui correspondent aux espaces réservés.



Modèles de balises



Les modèles de balises sont une forme étendue de littéraux de modèle. Les modèles étiquetés commencent par une fonction étiquetée qui analyse le littéral du modèle, donnant au développeur plus de contrôle sur le processus de génération de chaîne dynamique.



Dans l'exemple suivant, nous créons une fonction tagque nous prévoyons d'utiliser dans le rôle d'une fonction avec laquelle des opérations sont effectuées sur un modèle de balise. Le premier paramètre nommé de cette fonction stringsest un tableau de littéraux de chaîne. Les expressions en ligne sont placées dans le second paramètre en utilisant la syntaxe des paramètres restants . Afin de voir le contenu de ces paramètres, ils peuvent être affichés dans la console:



function tag(strings, ...expressions) {
  console.log(strings)
  console.log(expressions)
}


Si vous utilisez une fonction lors de la création d'un modèle de balise tag, vous pouvez obtenir la construction suivante:



const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.`


Étant donné que la fonction tageffectue une sortie vers la console stringset expressions, lors de l'exécution de ce code, ce qui suit sera envoyé à la console:



["This is a string with ", " and ", " and ", " interpolated inside."]
[true, false, 100]


Vous pouvez voir que le premier paramètre strings,, est un tableau contenant tous les littéraux de chaîne:



"This is a string with "
" and "
" and "
" interpolated inside."


Cet argument a également une propriété rawque vous pouvez appeler strings.raw. Il contient une ligne sur laquelle aucune séquence d'échappement n'a été traitée. Par exemple, ce \nsera juste un caractère \n, pas une commande de saut de ligne.



Le deuxième argument ,, ...expressionsest un tableau contenant toutes les expressions:



true
false
100


Le résultat est que tagles littéraux de chaîne et les expressions sont transmis à la fonction de modèle de balise . Notez que la fonction n'est pas requise pour renvoyer une chaîne. Il peut fonctionner avec les valeurs qui lui sont transmises et renvoyer n'importe quoi. Par exemple, nous pourrions avoir une fonction qui ne prête aucune attention à quoi que ce soit et qui renvoie simplement null. Voici comment la fonction est écrite returnsNulldans l'exemple suivant:



function returnsNull(strings, ...expressions) {
  return null
}

const string = returnsNull`Does this work?`
console.log(string)


À la suite de l'exécution de ce code, ce qui suit apparaîtra dans la console:



null


À titre d'exemple de ce que vous pouvez faire dans un modèle balisé, vous pouvez apporter des modifications à chacune des expressions, telles que des modifications pour inclure des expressions dans les balises HTML. Créons une fonction boldqui ajoute des balises à la <strong>fois </strong>le début et la fin de chaque expression:



function bold(strings, ...expressions) {
  let finalString = ''

  //    
  expressions.forEach((value, i) => {
    finalString += `${strings[i]}<strong>${value}</strong>`
  })

  //    
  finalString += strings[strings.length - 1]

  return finalString
}

const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`

console.log(string)


Ici, expressionsune boucle forEach est utilisée pour parcourir le tableau . Chaque élément est entouré de balises <strong></strong>.



This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.


Dans les bibliothèques JavaScript populaires, vous pouvez trouver plusieurs exemples d'utilisation de modèles de balises. Par exemple, la bibliothèque de balises graphql utilise un modèle littéral gqlpour analyser les chaînes de requête GraphQL et les transformer en un arbre de syntaxe abstraite (AST) que GraphQL comprend:



import gql from 'graphql-tag'

//        5
const query = gql`
  {
    user(id: 5) {
      firstName
      lastName
    }
  }
`


La bibliothèque de composants stylisés utilise également la fonctionnalité de balisage pour créer de nouveaux composants React à partir d'éléments DOM normaux et leur appliquer des styles CSS supplémentaires :



import styled from 'styled-components'

const Button = styled.button`
  color: magenta;
`

// <Button>     


Vous pouvez également utiliser la méthode standard String.raw pour l'appliquer à des modèles balisés afin d'empêcher le traitement des séquences d'échappement:



const rawString = String.raw`I want to write /n without it being escaped.`
console.log(rawString)


Ce qui suit apparaîtra dans la console après l'exécution de ce code:



I want to write /n without it being escaped.


Résultat



Dans cet article, nous nous sommes souvenus des informations de base sur les littéraux de chaîne ordinaires, formatés avec des guillemets simples ou doubles, et avons également parlé des littéraux de modèle et des modèles de balises. Les littéraux de modèle simplifient de nombreuses tâches de traitement de chaînes. En particulier, nous parlons d'incorporer différentes valeurs dans des chaînes et de créer des chaînes multilignes sans utiliser de concaténation ou d'échappement. Le balisage est une fonctionnalité littérale de modèle avancée utile qui est utilisée dans de nombreuses bibliothèques populaires.



Utilisez-vous des littéraux de modèle?






All Articles