在 JavaScript 中创建多行字符串

IT技术 javascript string multiline heredoc
2020-12-09 01:05:56

我在 Ruby 中有以下代码。我想将此代码转换为 JavaScript。JS中的等价代码是什么?

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

更新:

ECMAScript 6 (ES6) 引入了一种新的文字类型,即模板文字它们具有许多功能,包括可变插值等,但对于这个问题最重要的是,它们可以是多行的。

模板文字由反引号分隔

var html = `
  <div>
    <span>Some HTML here</span>
  </div>
`;

(注意:我不提倡在字符串中使用 HTML)

浏览器支持还可以,但您可以使用转译器来提高兼容性。


原始 ES5 答案:

Javascript 没有 here-document 语法。但是,您可以转义文字换行符,这很接近:

"foo \
bar"
@Nate 它在ECMA-262 第 5 版第 7.8.4 节中指定并称为LineContinuation:“行终止符不能出现在字符串文字中,除非作为LineContinuation 的一部分以产生空字符序列。导致 a 的正确方法要成为字符串文字的字符串值的一部分的行终止符是使用转义序列,例如 \n 或 \u000A。”
2021-02-07 01:05:56
当浏览器不一致地对待它时,我不明白你为什么要这样做。跨多行的“line1\n”+“line2”足够可读,并且您可以保证一致的行为。
2021-02-08 01:05:56
请注意:有些浏览器会在连续处插入换行符,有些则不会。
2021-02-11 01:05:56
“浏览器支持正常”... IE11 不支持 - 不正常
2021-02-17 01:05:56
Visual Studio 2010 似乎也被这种语法弄糊涂了。
2021-02-28 01:05:56

ES6 更新:

正如第一个答案提到的,使用 ES6/Babel,您现在可以简单地使用反引号创建多行字符串:

const htmlString = `Say hello to 
multi-line
strings!`;

插值变量是一个流行的新特性,它带有反引号分隔的字符串:

const htmlString = `${user.name} liked your post about strings`;

这只是转化为串联:

user.name + ' liked your post about strings'

原始 ES5 答案:

Google 的 JavaScript 样式指南建议使用字符串连接而不是转义换行符:

不要这样做:

var myString = 'A rather long string of English text, an error message \
                actually that just keeps going and going -- an error \
                message to make the Energizer bunny blush (right through \
                those Schwarzenegger shades)! Where was I? Oh yes, \
                you\'ve got an error and all the extraneous whitespace is \
                just gravy.  Have a nice day.';

每行开头的空格在编译时无法安全地去除;斜线后面的空格会导致棘手的错误;虽然大多数脚本引擎都支持这一点,但它不是 ECMAScript 的一部分。

改用字符串连接:

var myString = 'A rather long string of English text, an error message ' +
               'actually that just keeps going and going -- an error ' +
               'message to make the Energizer bunny blush (right through ' +
               'those Schwarzenegger shades)! Where was I? Oh yes, ' +
               'you\'ve got an error and all the extraneous whitespace is ' +
               'just gravy.  Have a nice day.';
请注意,IE11、Firefox 31、Chrome 35 或 Safari 7 不支持模板字符串。请参阅kangax.github.io/compat-table/es6
2021-02-07 01:05:56
令人惊讶的是,经过这么多年的字符串连接仍然是最好/最安全/最合规的方式。模板文字(上面的答案)在 IE 中不起作用,转义行只是一团糟,你很快就会后悔
2021-02-25 01:05:56
我不明白谷歌的建议。除了非常旧的浏览器之外,所有浏览器都支持反斜杠后跟换行符的方法,并且将来会继续这样做以实现向后兼容性。您唯一需要避免的情况是,您是否需要确保在每行末尾添加一个且仅一个换行符(或不添加换行符)(另请参阅我对已接受答案的评论)。
2021-03-01 01:05:56
@MattBrowne Google 的建议已经被他们记录在案,按原因的重要性排序:(1)每行开头的空格 [在示例中,您不希望字符串中出现该空格,但它在代码中看起来更好] (2) 斜杠后面的空格会导致棘手的错误[如果你用\ `\`结束一行,就很难注意到] 和(3) 虽然大多数脚本引擎支持这一点,但它不是ECMAScript 的一部分[即为什么使用非标准功能?] 记住这是一个风格指南,它是关于使代码易于阅读+维护+调试:不仅仅是“它工作”正确。
2021-03-01 01:05:56
发现旧版本的 Android 不支持反引号的困难方式,因此如果您有一个使用 webView 的 Android 应用程序,您的反引号会导致您的应用程序无法运行!
2021-03-08 01:05:56

该模式text = <<"HERE" This Is A Multiline String HERE在 js 中不可用(我记得在我过去的 Perl 时代经常使用它)。

为了保持对复杂或长多行字符串的监督,我有时使用数组模式:

var myString = 
   ['<div id="someId">',
    'some content<br />',
    '<a href="#someRef">someRefTxt</a>',
    '</div>'
   ].join('\n');

或者已经显示的模式匿名(转义换行符),这可能是您代码中的一个丑陋的块:

    var myString = 
       '<div id="someId"> \
some content<br /> \
<a href="#someRef">someRefTxt</a> \
</div>';

这是另一个奇怪但有效的“技巧” 1

var myString = (function () {/*
   <div id="someId">
     some content<br />
     <a href="#someRef">someRefTxt</a>
    </div>        
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];

外部编辑:jsfiddle

ES20xx支持使用模板字符串跨越多行的字符串

let str = `This is a text
    with multiple lines.
    Escapes are interpreted,
    \n is a newline.`;
let str = String.raw`This is a text
    with multiple lines.
    Escapes are not interpreted,
    \n is not a newline.`;

1注意:这将在缩小/混淆您的代码后丢失

+1 表示优雅的替代方案,它不仅在所有浏览器中都以相同的方式工作,而且还面向未来。
2021-02-14 01:05:56
@KooiInc 您的测试从已经创建的数组开始,这会扭曲结果。如果加上数组的初始化,直接串联会更快jsperf.com/string-concat-without-sringbuilder/7stackoverflow.com/questions/51185/...作为换行的技巧,可能没问题,但绝对是做比它应该做的更多的工作
2021-02-17 01:05:56
阵列模式更具可读性,应用程序的性能损失通常可以忽略不计。正如该性能测试所示,即使是 IE7 也可以每秒执行数万次操作。
2021-02-28 01:05:56
请不要使用数组模式。在大多数情况下,它会比普通的字符串连接慢。
2021-03-02 01:05:56
@BMiner:1)“过早的优化是万恶之源”——Donald Knuth,2)“可读性”在旁观者眼中
2021-03-05 01:05:56

可以在纯 JavaScript 中使用多行字符串。

此方法基于函数的序列化,定义为依赖于实现它确实适用于大多数浏览器(见下文),但不能保证它在未来仍然有效,所以不要依赖它。

使用以下功能:

function hereDoc(f) {
  return f.toString().
      replace(/^[^\/]+\/\*!?/, '').
      replace(/\*\/[^\/]+$/, '');
}

你可以在这里拥有这样的文件:

var tennysonQuote = hereDoc(function() {/*!
  Theirs not to make reply,
  Theirs not to reason why,
  Theirs but to do and die
*/});

该方法已在以下浏览器中成功测试(未提及=未测试):

  • IE 4 - 10
  • 歌剧 9.50 - 12(不在 9-)
  • Safari 4 - 6(不在 3-)
  • 铬 1 - 45
  • Firefox 17 - 21(不在 16- 中
  • Rekonq 0.7.0 - 0.8.0
  • Konqueror 4.7.4 不支持

不过要小心你的压缩器。它倾向于删除评论。对于YUI 压缩器,以/*!(如我使用的)开头的注释将被保留。

我认为真正的解决方案是使用CoffeeScript

ES6 更新:您可以使用反引号代替创建带有注释的函数并在注释上运行 toString。正则表达式需要更新为仅去除空格。您还可以使用字符串原型方法来执行此操作:

let foo = `
  bar loves cake
  baz loves beer
  beer loves people
`.removeIndentation()

有人应该写这个 .removeIndentation 字符串方法...;)

a.toString().substring(15, a.toString().length-4) 也可以工作,并且不需要扫描整个字符串(尽管它很可能会扫描并且计数无论如何都会使它再次扫描。哦,好吧.)
2021-02-08 01:05:56
@uosɐſ:它是故意的,它必须在规范中;或者如此广泛使用,浏览器制造商不想删除这个“意外”功能。感谢您的实验...尝试一些咖啡脚本。
2021-02-12 01:05:56
非常方便。我将它用于(Jasmine)单元测试,但避免将它用于生产代码。
2021-02-16 01:05:56
jsfiddle.net/fqpwf适用于 Chrome 13 和 IE8/9,但不适用于 FF6。我不想这么说,但我喜欢它,如果它可以是每个浏览器的一个有意特性(这样它就不会消失),我会使用它。
2021-02-20 01:05:56
什么!?创建和反编译一个函数以将多行注释破解为多行字符串?现在这很丑陋。
2021-03-02 01:05:56

你可以这样做...

var string = 'This is\n' +
'a multiline\n' + 
'string';
第一个例子很棒也很简单。比 \ 方法要好得多,因为我不确定浏览器如何将反斜杠作为转义字符和多行字符处理。
2021-02-07 01:05:56
e4x.js将是很好的面向未来的解决方案
2021-02-08 01:05:56
2021-02-17 01:05:56