在JavaScript中创建多行字符串

3420

我有以下的 Ruby 代码。我想将这段代码转换成 JavaScript。请问在 JavaScript 中等价的代码是什么?

text = <<"HERE"
This
Is
A
Multiline
String
HERE
43个回答

29
使用模板字面量(template literals),即用反引号(` `)括起来的字符串,在JavaScript中打印多行文本非常简单。你还可以在模板字符串中使用变量,像这样 (` name is ${value} `)。

您还可以:

const value = `multiline`
const text = `This is a
${value}
string in js`;
console.log(text);

25

我喜欢这种语法和缩进:

string = 'my long string...\n'
       + 'continue here\n'
       + 'and here.';

(但实际上不能被视为多行字符串)


3
我使用这种方式,只不过我把“+”放在前一行的末尾,以明确表明该语句将继续在下一行。不过你的方法可以更加均匀地对齐缩进。 - Sean
@Sean 我也使用这种方式,但我仍然更喜欢在每行开头加上 '+',并将最后的 ';' 放在新的一行,因为我觉得这样更加“正确”。 - AgelessEssence
7
将“+”放在开头,允许我们在不编辑其他行的情况下注释掉该行,特别是当它是序列的第一行或最后一行时。 - moliad
3
我也更喜欢在前面添加“+”符号,因为视觉上我不需要扫描到行末才知道下一行是延续。 - Daniel Sokolowski

21
Downvoters: 这段代码仅供参考。
此代码已在Mac上的Fx 19和Chrome 24中进行了测试。 演示

var new_comment; /*<<<EOF 
    <li class="photobooth-comment">
       <span class="username">
          <a href="#">You</a>:
       </span>
       <span class="comment-text">
          $text
       </span> 
       @<span class="comment-time">
          2d
       </span> ago
    </li>
EOF*/
// note the script tag here is hardcoded as the FIRST tag 
new_comment=document.currentScript.innerHTML.split("EOF")[1]; 
document.querySelector("ul").innerHTML=new_comment.replace('$text','This is a dynamically created text');
<ul></ul>


17
那太可怕了。+1。而且你可以使用document.currentScript代替getElement... - Orwellophile
1
在OSX的Chrome中未定义“you”。 - mplungjan
1
jsfiddle-fixed - 我必须在控制台中全局定义“you”。现在可以工作(chrome/osx)。将注释添加到变量中的好处是您不在函数上下文中,jsfiddle-function-heredoc 虽然函数的东西对于类方法很酷。无论如何,最好传递一个替换 { this: that } 对象。尝试将某些疯狂的东西推向极限也很有趣 :) - Orwellophile
1
忘记那些喷子吧,这是除了ES6之外唯一正确的答案。所有其他答案都需要拼接、计算或转义。这实际上非常酷,我将把它用作我正在从事的游戏中添加文档的一种方式。只要不将此技巧用于可能引发错误的任何内容(我可以看到有人会说“分号,傻瓜。让我们把注释放在下一行。”然后它就会破坏你的代码),但是,在我的业余游戏中,这真的很重要吗?不,我可以将这个酷技巧用于一些有用的东西。非常好的答案。 - Thomas Dignan
2
我从未有勇气在生产代码中使用这种技术,但我在单元测试中经常使用它,因为通常最容易的方法是将某些结构的值转储为(相当长的)字符串,并将其与应该的值进行比较。 - Ben McIntyre
显示剩余5条评论

19

有一个能让它变得很漂亮的库:

https://github.com/sindresorhus/multiline

之前的内容

var str = '' +
'<!doctype html>' +
'<html>' +
'   <body>' +
'       <h1>❤ unicorns</h1>' +
'   </body>' +
'</html>' +
'';

之后

var str = multiline(function(){/*
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>
*/});

1
这个支持在 nodejs 中使用,但在浏览器中使用时必须小心。 - Huei Tan
3
文档表明它在浏览器中也能工作。这很合理-它只是Function.prototype.String() - mikemaccana
是的,但它说:“虽然在浏览器中可以正常工作,但主要用于Node.js。使用时请自行承担风险。虽然在浏览器中可以正常工作,但主要用于Node.js。使用时请自行承担风险。”(只是要小心 XD) - Huei Tan
@HueiTanYep 我读了那部分。但是Function.prototype.toString()非常稳定和众所周知。 - mikemaccana
1
对我来说最好的答案,因为它至少实现了多行,而没有中间的垃圾(开头和结尾的垃圾我可以处理)。 - Damien Golding

17

发现这里有很多过度工程化的答案。在我看来,最好的两个答案是:

1:

 let str = `Multiline string.
            foo.
            bar.`

最终记录如下:

Multiline string.
           foo.
           bar.  

2:

let str = `Multiline string.
foo.
bar.`

它可以正确记录日志,但如果str嵌套在函数/对象等中,那么在脚本文件中它会显得很丑陋:

Multiline string.
foo.
bar.

这是一个用正则表达式编写的简单答案,可以正确记录该字符串:

let str = `Multiline string.
           foo.
           bar.`.replace(/\n +/g, '\n');

请注意,这并不是完美的解决方案,但如果您确定在换行符(\n)之后至少会出现一个空格(+表示至少出现一次),它仍然可以奏效。它还可以与*(零个或多个)一起使用。

您可以更加明确地使用{n,},它表示至少出现n次。


6
为什么不直接使用[ "line", "line2", "line3" ].join("\n")呢? - Kaz

12

在 JavaScript 中的等效代码是:

var text = `
This
Is
A
Multiline
String
`;

这里是规范。在这个页面底部可以看到浏览器支持情况。这里也提供一些示例


11

这在IE,Safari,Chrome和Firefox中有效:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<div class="crazy_idea" thorn_in_my_side='<table  border="0">
                        <tr>
                            <td ><span class="mlayouttablecellsdynamic">PACKAGE price $65.00</span></td>
                        </tr>
                    </table>'></div>
<script type="text/javascript">
    alert($(".crazy_idea").attr("thorn_in_my_side"));
</script>

8
想一想,你认为它有效吗?你不觉得它可能会引起显示问题吗? - Sk8erPeter
6
为什么会有踩?这是一个有创意的回答,虽然不太实用! - dotancohen
3
不,不是这样的。更好的做法是使用模板:$.tmpl()(http://api.jquery.com/tmpl/)或EJS(http://embeddedjs.com/getting_started.html)等。一个被投票降低的原因是它与有效代码相差甚远,使用它可能会导致严重的显示问题。 - Sk8erPeter
我希望没有人在实践中使用这个答案,但这是一个不错的想法。 - DCShannon
在HTML中存在单引号'的边缘情况。在这种情况下,您可能需要使用HTML实体&#39; - borracciaBlu

11

总之,在用户JavaScript编程(Opera 11.01)中,我尝试了以下两种方法:

所以,我推荐Opera用户使用有效的方法。与作者所说的不同:

它不能在Firefox或Opera上工作;只能在IE、chrome和safari上工作。

它在Opera 11中确实起作用。至少在用户JS脚本中是如此。很遗憾我不能对单独的答案发表评论或点赞,如果可能的话,请有更高权限的人替我完成。


这是我的第一个实际评论。我在2天前获得了upvote特权,所以我立即upvote了上面提到的一个答案。感谢任何upvote了我微不足道的帮助的人。 - Tyler
感谢所有实际点赞这个答案的人:我现在有足够的特权来发布普通评论了!再次感谢。 - Tyler

11

Exact

Ruby 生成: "This\nIs\nA\nMultiline\nString\n" - 下面的JS代码生成了完全相同的字符串

text = `This
Is
A
Multiline
String
`

// TEST
console.log(JSON.stringify(text));
console.log(text);

这是对Lonnie Best的回答进行的改进,因为他回答中的换行符并不完全与ruby输出中的位置相同。

文本是字符串,为什么要使用 JSON.stringify? - FlatLander
1
@FlatLander 这只是为了测试 - 查看换行符\n的确切位置(与Ruby输出进行比较(工作示例链接在答案中)) - 这是Lonnie答案的改进,因为他答案中的换行符位置与Ruby输出不完全相同。 - Kamil Kiełczewski

10

我的扩展是基于https://dev59.com/c3RA5IYBdhLWcg3w2xsI#15558082的。

它期望以这种形式的注释出现:/*! 任意多行注释 */其中符号!用于防止被缩小(至少对于YUI压缩器)移除

Function.prototype.extractComment = function() {
    var startComment = "/*!";
    var endComment = "*/";
    var str = this.toString();

    var start = str.indexOf(startComment);
    var end = str.lastIndexOf(endComment);

    return str.slice(start + startComment.length, -(str.length - end));
};

例子:

var tmpl = function() { /*!
 <div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
    </ul>
 </div>
*/}.extractComment();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接