33

假设我们有一个多行 es6 Template-String 来描述请求的一些 URL 参数:

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

有没有办法在反引号模板字符串中添加评论?像:

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

4 回答 4

86

选项 1:插值

我们可以创建返回空字符串的插值块,并将注释嵌入其中。

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

console.log(fields);

选项 2:标记模板

使用标记模板,我们可以清除注释并重建字符串。这是一个简单的commented函数,它使用Array.map(),String.replace()和正则表达式(需要一些工作)来清除注释并返回干净的字符串:

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);

于 2016-10-14T15:39:56.680 回答
14

不。

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

如果您查看规范的§11.8.6,您可以看到在反引号分隔符之间识别的唯一标记是TemplateCharacters,它接受转义序列、换行符和普通字符。在§A.1中,SourceCharacter被定义为任何 Unicode 点(11.8.6 中排除的点除外)。

于 2016-10-14T15:27:25.840 回答
14

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

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

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

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

请注意,您必须将 ''(一个空字符串)放在 ${ } 大括号中,以便 Javascript 具有要插入的表达式。不这样做会导致运行时错误。引号可以放在评论之外的任何地方。

我不是这个的超级粉丝。它非常丑陋并且使评论变得很麻烦,更不用说在大多数 IDE 中切换评论变得很困难。

就个人而言,我尽可能使用模板字符串,因为它们比常规字符串更有效,并且它们从字面上捕获您想要的所有文本,大部分没有转义。你甚至可以把函数调用放在那里!

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

.

现在回答问题的意图:

如何编写逗号分隔的列表字符串,每行都有注释?

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

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

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

似乎您仅使用模板文字是为了满足在每行上没有引号的愿望,从而最大限度地减少“字符串”查询参数在 url 和代码中查看时的认知失调。你应该知道这会保留换行符,我怀疑你想要那个。改为考虑:

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

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

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

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

第一个正则表达式将查找并用空字符串 ( '') 替换以下所有实例:一个或多个在双斜杠之前的空格字符(每个斜杠都由反斜杠转义),然后是空格和换行符。如果你想使用/* multiline */注释,这个正则表达式会变得有点复杂,你必须.replace()在最后添加另一个:

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

该正则表达式只能在您删除\n换行符之后才能使用,否则正则表达式将不匹配 now-not-multiline 注释。看起来像这样:

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/。我现在超级好奇!

于 2018-01-31T02:54:57.397 回答
2

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

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

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

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

更新

请注意,将编程数据存储在字符串中通常是一个坏主意:将它们存储为命名变量或对象属性。由于您的评论反映了您只是将一堆东西转换为 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 中的那些)更透明的东西。

于 2016-10-14T15:28:45.277 回答