ES6 modèles littéraux Vs chaînes concaténées

J'ai le code suivant pour ECMA-Script-6 template literals

let person = {name: 'John Smith'};   
let tpl = `My name is ${person.name}.`;    
let MyVar="My name is "+ person.name+".";

console.log("template literal= "+tpl);  
console.log("my variable = "+MyVar);

La sortie est la suivante:

template literal= My name is John Smith.
my variable = My name is John Smith.

Ce est le violon. J'ai essayé de chercher la différence exacte mais je ne l'ai pas trouvée, Ma question Est Quelle est la différence entre ces deux déclarations,

  let tpl = `My name is ${person.name}.`;    

Et

  let MyVar = "My name is "+ person.name+".";

Je suis déjà capable d'obtenir la chaîne MyVar concaténée avec person.name ici, alors quel serait le scénario pour utiliser le littéral du modèle ?

44
demandé sur Naeem Shaikh 2014-12-19 14:24:51

4 réponses

Si vous utilisez des littéraux de modèle uniquement avec des espaces réservés (par exemple ${expression}) comme dans l'exemple de la question, le résultat est le même que la concaténation de chaînes. Subjectivement, il semble mieux et est plus facile à lire, en particulier pour les chaînes multi-lignes ou les chaînes contenant à la fois ' et " puisque vous n'avez plus besoin d'échapper à ces caractères.

La lisibilité est une grande fonctionnalité, mais la chose la plus intéressante à propos des modèles sont template Tagged les littéraux de:

let person = {name: 'John Smith'};   
tag `My name is ${person.name}.`

, Dans la deuxième ligne de cet exemple, une fonction nommée tag est appelé. Le contenu de la chaîne de modèle est divisé en plusieurs variables auxquelles vous pouvez accéder dans les arguments de la fonction tag: sections littérales (dans cet exemple My name is et .) et substitutions (John Smith). Le littéral du modèle sera évalué à n'importe quel retour de la fonction tag.

Le wiki ECMAScript répertorie certains cas d'utilisation, comme s'échapper automatiquement ou entrée de codage, ou localisation. Vous pouvez créer une fonction de balise nommée msg qui recherche les parties littérales comme My name is et les remplace par des traductions dans la langue locale actuelle, par exemple en allemand:

console.log(msg`My name is ${person.name}.`) // Output: Mein Name ist John Smith.

La valeur renvoyée par la fonction tag ne doit même pas être une chaîne. Cet exemple de sélecteur de requête {[18] } est censé renvoyer une collection de nœuds DOM:

$`a.${className}[href=~'//${domain}/']`
54
répondu kapex 2018-08-01 11:07:07

ES6 arrive avec un nouveau type de littéral de chaîne, en utilisant le \ back-tick` comme délimiteur. Ces littéraux permettent d'intégrer des expressions d'interpolation de chaîne de base, qui sont ensuite automatiquement analysées et évaluées.

let actor = {name: 'RajiniKanth', age: 68};

let oldWayStr = "<p>My name is " + actor.name + ",</p>\n" +
  "<p>I am " + actor.age + " old</p>\n";

let newWayHtmlStr =
 `<p>My name is ${actor.name},</p>
  <p>I am ${actor.age} old</p>`;

console.log(oldWayStr);
console.log(newWayHtmlStr);

Comme vous pouvez le voir, nous avons utilisé le ..` autour d'une série de caractères, qui sont interprétés comme un littéral de chaîne, mais toutes les expressions de la forme ${..} sont analysées et évaluées immédiatement en ligne.

Un avantage vraiment agréable de les littéraux de chaîne interpolés sont autorisés à se diviser sur plusieurs lignes:

var Actor = {"name" : "RajiniKanth"};

var text =
`Now is the time for all good men like ${Actor.name}
to come to the aid of their
country!`;
console.log( text );
// Now is the time for all good men
// to come to the aid of their
// country!

Expressions Interpolées

Toute expression valide est autorisée à apparaître à l'intérieur de ${..} dans une chaîne interpolée lit‐ eral, y compris les appels de fonction, les appels d'expression de fonction en ligne, et même d'autres interpo‐ lated string literals!

function upper(s) {
 return s.toUpperCase();
}
var who = "reader"
var text =
`A very ${upper( "warm" )} welcome
to all of you ${upper( `${who}s` )}!`;
console.log( text );
// A very WARM welcome
// to all of you READERS!

Ici, le littéral de chaîne interpolée interne \${who} s` était un peu plus pratique pour nous lors de la combinaison de la variable who avec la chaîne "s" , par opposition à qui + "s". Aussi pour garder une note est une chaîne interpolée littérale est juste lexically scoped où il apparaît, pas dynamically scoped en aucune façon

function foo(str) {
 var name = "foo";
 console.log( str );
}
function bar() {
 var name = "bar";
 foo( `Hello from ${name}!` );
}
var name = "global";
bar(); // "Hello from bar!"

L'Utilisation du template literal pour le HTML est nettement plus lisible en réduisant l'ennui.

La voie ancienne:

'<div class="' + className + '">' +
  '<p>' + content + '</p>' +
  '<a href="' + link + '">Let\'s go</a>'
'</div>';

Avec ES6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
  • Votre chaîne peut s'étendre sur plusieurs lignes.
  • vous n'avez pas besoin d'échapper aux caractères de citation.
  • vous pouvez éviter les regroupements comme: '" > '
  • vous ne le faites pas utiliser l'opérateur plus.

Tag Modèles Littéraux

Nous pouvons également marquer une chaîne template, quand une chaîne template est marquée, les literals et les substitutions sont passées à la fonction qui renvoie la valeur résultante.

function myTaggedLiteral(strings) {
  console.log(strings);
}

myTaggedLiteral`test`; //["test"]

function myTaggedLiteral(strings,value,value2) {
  console.log(strings,value, value2);
}
let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

Nous pouvons utiliser l'opérateur spread ici pour passer plusieurs valeurs. Le premier argument - nous l'avons appelé strings-est un tableau de toutes les chaînes simples (les choses entre les expressions interpolées).

Nous nous rassemblons alors tous les arguments suivants dans un tableau appelé values en utilisant le ... gather/rest operator, bien que vous pourriez bien sûr les avoir laissés en tant que paramètres nommés individuels en suivant le paramètre strings comme nous l'avons fait ci-dessus (value1, value2 etc).

function myTaggedLiteral(strings,...values) {
  console.log(strings);
  console.log(values);    
}

let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

Les argument(s) rassemblés dans notre tableau de valeurs sont les résultats des expressions d'interpolation déjà évaluées trouvées dans le littéral de chaîne. Un tagged string literal est comme une étape de traitement après l'évaluation des interpolations mais avant la compilation de la valeur de chaîne finale, vous permettant plus de contrôle sur la génération de la chaîne à partir du littéral. Regardons un exemple de création d'un re-usable templates.

const Actor = {
  name: "RajiniKanth",
  store: "Landmark"
}

const ActorTemplate = templater`<article>
  <h3>${'name'} is a Actor</h3>
  <p>You can find his movies at ${'store'}.</p>

</article>`;

function templater(strings, ...keys) {
  return function(data) {
  let temp = strings.slice();
  keys.forEach((key, i) => {
  temp[i] = temp[i] + data[key];
  });
  return temp.join('');
  }
};

const myTemplate = ActorTemplate(Actor);
console.log(myTemplate);

Chaînes Brutes

Nos fonctions de balise reçoivent un premier argument que nous avons appelé strings, qui est un array. Mais il y a un bit supplémentaire de données inclus: les versions brutes non traitées de toutes les chaînes. Vous pouvez accéder à ces valeurs de chaîne brutes en utilisant la propriété .raw, comme ceci:

function showraw(strings, ...values) {
 console.log( strings );
 console.log( strings.raw );
}
showraw`Hello\nWorld`;

Comme vous pouvez le voir, la version raw de la chaîne conserve la séquence \n échappée, tandis que la version traitée de la chaîne la traite comme une vraie nouvelle ligne non échappée. {[11] } est livré avec une fonction intégrée qui peut être utilisée comme une balise littérale de chaîne: String.raw(..). Il passe simplement par les versions brutes du strings:

console.log( `Hello\nWorld` );
/* "Hello
World" */

console.log( String.raw`Hello\nWorld` );
// "Hello\nWorld"
8
répondu Thalaivar 2016-10-15 18:14:11

Il est beaucoup plus propre et comme indiqué dans les commentaires, est une caractéristique commune dans d'autres langues. L'autre chose que j'ai trouvée agréable était les sauts de ligne, très utiles lors de l'écriture de chaînes.

let person = {name: 'John Smith', age: 24, greeting: 'Cool!' };

let usualHtmlStr = "<p>My name is " + person.name + ",</p>\n" +
                   "<p>I am " + person.age + " old</p>\n" +
                   "<strong>\"" + person.greeting +"\" is what I usually say</strong>";


let newHtmlStr = 
 `<p>My name is ${person.name},</p>
  <p>I am ${person.age} old</p>
  <p>"${person.greeting}" is what I usually say</strong>`;


console.log(usualHtmlStr);
console.log(newHtmlStr);
4
répondu Rigotti 2014-12-19 13:32:52

Alors que, ma réponse ne répond pas directement à la question. J'ai pensé qu'il pourrait être intéressant de souligner un inconvénient de l'utilisation de littéraux de modèle en faveur de la jointure de tableau.

Disons que j'ai

let patient1 = {firstName: "John", lastName: "Smith"};
let patient2 = {firstName: "Dwayne", lastName: "Johnson", middleName: "'The Rock'"};

Donc, certains patients ont un middleName et d'autres pas.

Si je voulais une chaîne représentant le nom complet d'un patient

let patientName = `${patient1.firstName} ${patient1.middleName} ${patient1.lastName}`;

Alors cela deviendrait "John Undefined Smith"

Cependant si je l'ai fait

let patientName = [patient1.firstName, patient1.middleName,  patient1.lastName].join(" ");

Alors cela deviendrait juste ,"John Smith"

1
répondu Dhruv Prakash 2018-07-10 15:51:36