10 votes

Est-il possible d'avoir un commentaire à l'intérieur d'un modèle de chaîne es6 ?

Supposons que nous ayons un Template-String es6 multiligne pour décrire, par exemple, certains paramètres d'URL pour une requête :

const fields = `
    id,
    message,
    created_time,
    permalink_url,
    type
`;

Existe-t-il un moyen d'avoir des commentaires à l'intérieur de la chaîne de caractères du modèle de backtick ? Comme :

const fields = `
    // post id
    id,
    // post status/message
    message,
    // .....
    created_time,
    permalink_url,
    type
`;

39voto

Ori Drori Points 65611

Option 1 : Interpolation

Nous pouvons créer interpolation qui renvoient une chaîne vide, et y insèrent les commentaires.

const fields = `
  id, ${ /* post id */'' }
  message, ${ /* post status/message */'' }
  created_time,
  permalink_url,
  type
`;

console.log(fields);

Option 2 : Modèles étiquetés

Utilisation modèles étiquetés nous pouvons effacer les commentaires et reconstituer les chaînes. Voici un exemple simple de commented qui utilise la fonction Array.map() , String.replace() et une expression regex (qui a besoin d'être retravaillée) pour effacer les commentaires et renvoyer la chaîne propre :

const commented = (strings, ...values) => {
  const pattern = /\/{2}.+$/gm; // basic idea

  return strings
    .map((str, i) => 
      `${str.replace(pattern, '')}${values[i] !== undefined ? values[i] : ''}`)
    .join('');
};

const d = 10;
const fields = commented`
  ${d}
  id, // post ID
  ${d}
  message, // post/status message
  created_time, // ...
  permalink_uri,
  type
`;

console.log(fields);

8voto

ssube Points 8838

Non.

Cette syntaxe est valide, mais elle renvoie une chaîne de caractères contenant \n// post id\nid plutôt que de supprimer les commentaires et de créer une chaîne sans eux.

Si vous regardez §11.8.6 de la spécification vous pouvez voir que le seul élément reconnu entre les délimiteurs de bâtons est Caractères de modèle qui accepte les séquences d'échappement, les sauts de ligne et les caractères normaux. En §A.1 , Caractère source est défini comme étant n'importe quel point Unicode (à l'exception de ceux exclus dans 11.8.6).

8voto

Metagrapher Points 2891

Je sais que c'est une vieille réponse, mais en voyant les réponses ci-dessus, je me sens obligé de répondre à la fois à la question pure et à l'esprit de la question posée.

Peut-on utiliser des commentaires dans les chaînes littérales des modèles ?

Oui. Oui, vous pouvez. Mais ce n'est pas joli.

const fields = `
    id, ${/* post ID */''}
    message, ${/* post/status message */''}
    created_time, ${/*... */''}
    permalink_url,
    type
`;

Notez que vous devez mettre '' (une chaîne vide) dans le ${ } afin que Javascript dispose d'une expression à insérer. Si vous ne le faites pas, vous obtiendrez une erreur d'exécution. Les guillemets peuvent être placés n'importe où à l'extérieur du commentaire.

Je n'en suis pas très fan. C'est assez laid et cela rend les commentaires encombrants, sans parler du fait qu'il est difficile d'alterner les commentaires dans la plupart des IDE.

Personnellement, j'utilise autant que possible des chaînes modèles, car elles sont un peu plus efficaces que les chaînes classiques et elles capturent littéralement tout le texte que vous voulez, la plupart du temps sans échappement. Vous pouvez même y placer des appels de fonction !

La chaîne de l'exemple ci-dessus sera toutefois un peu étrange et potentiellement inutile pour ce que vous recherchez, car il y aura un saut de ligne initial, un espace supplémentaire entre la virgule et le commentaire, ainsi qu'un saut de ligne final supplémentaire. La suppression de cet espace indésirable pourrait avoir un impact limité sur les performances. Vous pourriez utiliser une expression rationnelle pour cela, pour plus de rapidité et d'efficacité... plus d'informations à ce sujet ci-dessous...

.

Pour répondre à l'objet de la question :

Comment écrire une liste délimitée par des virgules, avec des commentaires sur chaque ligne ?

const fields = [
    "id", // post ID
    "message", // post/status message
    "created_time", //...
    "permalink_url",
    "type"
].join(",\n");

Joindre un tableau est une façon... (comme suggéré par @jared-smith )

Cependant, dans ce cas, vous créez un tableau et vous rejetez immédiatement les données organisées lorsque vous n'assignez que la valeur de retour de la fonction join() fonction. De plus, vous créez un pointeur de mémoire pour chaque chaîne du tableau, qui ne sera pas ramassé jusqu'à la fin du champ d'application. Dans ce cas, il peut être plus utile de capturer le tableau, en le joignant à la volée en fonction de l'utilisation, ou d'utiliser un modèle littéral et de commenter différemment votre implémentation, comme dans le style ghostDoc.

Il semble que vous n'utilisiez les littéraux de modèle que pour satisfaire le désir de ne pas avoir de guillemets sur chaque ligne, minimisant ainsi la dissonance cognitive entre les paramètres de requête "chaîne" tels qu'ils apparaissent dans l'url et le code. Vous devez être conscient que cela préserve les sauts de ligne, et je doute que ce soit ce que vous souhaitiez. Envisagez plutôt de le faire :

/****************
 * Fields:
 *   id : post ID
 *   message : post/status message
 *   created_time : some other comment...
 */
const fields = `
    id,
    message,
    created_time,
    permalink_uri,
    type
`.replace(/\s/g,'');

Cette méthode utilise une expression rationnelle pour filtrer tous les espaces blancs, tout en conservant une liste lisible et réorganisable. Tout ce que fait le littéral de la regex est de capturer les espaces blancs, puis la méthode replace remplace le texte capturé par '' (le g à la fin indique simplement à l'expression rationnelle de ne pas s'arrêter à la première correspondance qu'elle trouve, dans ce cas, le premier caractère de retour à la ligne).

ou, plus ennuyeux, vous pourriez simplement mettre les commentaires directement dans votre modèle littéral, puis les supprimer avec une regex :

const fields = `
    id, // post ID
    message, // post/status message
    created_time, // ...
    permalink_uri,
    type
`.replace(/\s+\/\/.*\*\/\n/g,'').replace(/\s/g,'');

Cette première regex trouvera et remplacera une chaîne vide ( '' ) toutes les occurrences de : un ou plusieurs caractères d'espacement qui précèdent une double barre oblique (chaque barre oblique est échappée par une barre oblique inverse) suivie d'un espacement et du caractère de retour à la ligne. Si vous voulez utiliser /* multiline */ cette regex devient un peu plus complexe, vous devrez ajouter une autre .replace() à l'extrémité :

.replace(/\/\*.*\*\//g,'')

Cette expression rationnelle ne peut être utilisée qu'après avoir supprimé l'élément \n ou l'expression rationnelle ne correspondra pas au commentaire qui n'est plus multiligne. Cela ressemblerait à quelque chose comme ceci :

const fields = `
    id, // post ID
    message, /* post/
                status message */
    created_time, // ...
    permalink_uri,
    type
`.replace(/\s+\/\/.*\n/g,'').replace(/\s/g,'').replace(/\/\*.*\*\//g,'');

Toutes les opérations ci-dessus aboutissent à la chaîne suivante :

"id,message,created_time,permalink_uri,type"

Il y a probablement un moyen de faire cela avec une seule regex, mais cela dépasse le cadre du présent document. D'ailleurs, je vous encourage à tomber amoureux des regex en jouant avec elles vous-même !

J'essaierai d'obtenir un https://jsperf.com/ Nous reviendrons sur ce point plus tard. Je suis très curieux maintenant !

2voto

Jared Smith Points 101

Il suffit de ne pas utiliser de chaînes de caractères :

const fields = [
    'id',  // comment blah blah
    'message',
    'created_time',
    'permalink_url',
    'type'
].join(',');

Vous payez le coût du tableau et de l'appel de méthode lors de l'initialisation (en supposant que la JIT ne soit pas assez intelligente pour l'optimiser entièrement).

Comme l'a souligné ssube, la chaîne résultante ne conservera pas les sauts de ligne ou les espaces blancs. En fonction de l'importance de ces éléments, vous pouvez ajouter manuellement des ' ' et des ' \n ' si nécessaire ou si vous décidez que vous n'avez pas vraiment besoin de commentaires en ligne.

MISE À JOUR

Il est à noter que le stockage de données programmatiques dans des chaînes de caractères est généralement considéré comme une mauvaise idée Les données sont stockées sous forme de variables nommées ou de propriétés d'objets. Puisque votre commentaire reflète le fait que vous convertissez juste un tas de choses en un objet url :

const makeQueryString = (url, data) => {
  return url + '?' + Object.keys(data)
    .map(k => `${k}=${encodeURIComponent(data[k))})
    .join('&');
};

let qs = makeQueryString(url, {
  id: 3,
  message: 'blah blah',
  // etc.
});

Vous avez maintenant des éléments plus faciles à modifier, à comprendre, à réutiliser et plus transparents pour les outils d'analyse de code (comme ceux de l'IDE de votre choix).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X