是否可以在 es6 模板字符串中进行评论?

Is it possible to have a comment inside a es6 Template-String?

假设我们有一个多行 es6 模板字符串来描述例如请求的一些 URL 参数:

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

有没有办法在反引号模板字符串中添加注释?喜欢:

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

没有。

该语法有效,但只会 return 包含 \n// post id\nid 的字符串,而不是删除注释并创建没有注释的字符串。

如果您查看 §11.8.6 of the spec, you can see that the only token recognized between the backtick delimiters is TemplateCharacters, which accepts escape sequences, line breaks, and normal characters. In §A.1SourceCharacter 被定义为任何 Unicode 点(11.8.6 中排除的点除外)。

只是不要使用模板字符串:

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

您在初始化时支付数组和方法调用的成本(假设 JIT 不够智能,无法完全优化它。

正如 ssube 所指出的,生成的字符串将不会保留换行符或空格。这取决于它的重要性,您可以在必要时手动添加 ' ' 和 '\n',或者决定您真的不需要那么严重的内联注释。

更新

请注意,将编程数据存储在字符串中通常被认为是 bad idea:将它们存储为命名变量或对象属性。由于您的评论反映出您只是将一堆东西转换成 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.
});

现在您拥有更容易更改、理解、重用并且对代码分析工具(例如您选择的 IDE 中的工具)更加透明的内容。

选项 1:插值

我们可以创建 interpolation 个 return 空字符串块,并将注释嵌入其中。

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

console.log(fields);

选项 2:标记模板

使用 tagged templates we can clear the comments and reconstruct the strings. Here is a simple commented function that uses Array.map(), String.replace() 和正则表达式(这需要一些工作)来清除注释,以及 return 干净的字符串:

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

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

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

console.log(fields);

我知道这是一个老答案,但看到上面的答案我觉得有必要既回答纯粹的问题,然后回答提问者问题的精神。

可以在模板文字字符串中使用注释吗?

是的。是的你可以。但这并不漂亮。

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

注意要在${ }大括号,以便 Javascript 有一个要插入的表达式。不这样做会导致运行时错误。引号可以放在评论之外的任何地方。

我不是这个的忠实粉丝。它非常丑陋并且使评论变得麻烦,没关系,在大多数 IDE 中切换评论变得困难。

就我个人而言,我会尽可能使用模板字符串,因为它们比常规字符串更高效,而且它们几乎可以捕获您想要的所有文本,而且大部分都不会转义。您甚至可以将函数调用放在那里!

上面示例中的字符串会有点奇怪,并且可能对您要查找的内容毫无用处,但是,因为会有一个初始换行符,逗号和逗号之间会有额外的 space评论,以及额外的最后换行符。删除不需要的 space 可能会对性能造成很小的影响。您可以为此使用正则表达式,以提高速度和效率,但是...更多内容如下...

.

现在回答问题的意图:

如何编写以逗号分隔的列表字符串,并在每一行上添加注释?

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

加入数组是一种方式...(如@jared-smith 所建议)

但是,在这种情况下,您正在创建一个数组,然后在您仅分配 join() 函数的 return 值时立即丢弃组织数据。不仅如此,您还在为数组中的每个字符串创建一个内存指针,直到作用域结束时才会被垃圾回收。在这种情况下,捕获数组、根据使用指示动态加入或使用模板文字并以不同方式注释您的实现可能更有用,例如 ghostDoc 样式。

您似乎只是在使用模板文字来满足每行不带引号的愿望,从而最大限度地减少 'string' 查询参数在 [=80= 中的认知失调] 和代码。你应该知道这会保留换行符,我怀疑你想要那个。考虑一下:

/****************
 * 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,'');

这使用正则表达式过滤掉所有白色space,同时保持列表可读和可重新排列。正则表达式文字所做的就是捕获白色 space 然后替换方法用 '' 替换捕获的文本(最后的 g 只是告诉正则表达式不要在第一个停止匹配它找到,在这种情况下,第一个换行符。)

或者,最讨厌的是,您可以将注释直接放在模板文字中,然后用正则表达式去除它们:

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

第一个正则表达式将查找并替换为空字符串 ('') 的所有实例:一个或多个白色space 双斜杠前面的字符(每个斜杠由反斜杠转义) ) 后跟 whitespace 和换行符。如果你想使用 /* multiline */ 评论,这个正则表达式会变得有点复杂,你必须在最后添加另一个 .replace()

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

该正则表达式只能在您删除 \n 换行符后才能使用,否则正则表达式将无法匹配现在不多行的注释。那看起来像这样:

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

以上所有将导致此字符串:

"id,message,created_time,permalink_uri,type"

可能有一种方法可以只用一个正则表达式来做到这一点,但这确实超出了这里的范围。此外,我鼓励您通过自己动手来爱上正则表达式!

稍后我会尝试 https://jsperf.com/ 讨论这个问题。我现在超级好奇!