Creating multiline strings in JavaScript
我用Ruby编写了以下代码。我想把这段代码转换成JavaScript。JS中的等效代码是什么?
1 2 3 4 5 6 7 | text = <<"HERE" This Is A Multiline String HERE |
更新:
ecmascript 6(es6)引入了一种新的文本类型,即模板文本。它们有许多特性,变量插值等,但最重要的是,对于这个问题,它们可以是多行的。
模板文本由反勾号分隔:
1 2 3 4 5 | var html = ` <span>Some HTML here</span> `; |
(注意:我不主张在字符串中使用HTML)
浏览器支持是可以的,但您可以使用蒸腾器更兼容。
原始ES5答案:javascript没有here文档语法。但是,您可以避开文本换行符,换行符很接近:
1 2 | "foo \\ bar" |
ES6更新:
正如第一个答案所提到的,使用ES6/Babel,您现在可以通过使用倒勾来创建多行字符串:
1 2 3 | const htmlString = `Say hello to multi-line strings!`; |
插入变量是一种流行的新功能,它附带反勾号分隔字符串:
1 | const htmlString = `${user.name} liked your post about strings`; |
这就是串联:
1 | user.name + ' liked your post about strings' |
原始ES5答案:
Google's JavaScript style guide recommends to use string concatenation instead of escaping newlines:
Do not do this:
1
2
3
4
5
6 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.';The whitespace at the beginning of each line can't be safely stripped at compile time; whitespace after the slash will result in tricky errors; and while most script engines support this, it is not part of ECMAScript.
Use string concatenation instead:
1
2
3
4
5
6 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.';
模式
为了保持对复杂或长多行字符串的监督,我有时使用数组模式:
1 2 3 4 5 6 7 | var myString = ['', 'some content<br />', 'someRefTxt', '' ].join('\ '); |
或者匿名模式已经显示(转义换行符),这可能是代码中一个丑陋的块:
1 2 3 4 5 | var myString = ' \\ some content<br /> \\ someRefTxt \\ '; |
这是另一个奇怪但有效的"技巧"1:
1 2 3 4 5 6 | var myString = (function () {/* some content<br /> someRefTxt */}).toString().match(/[^]*\\/\\*([^]*)\\*\\/\\}$/)[1]; |
外部编辑:jsFiddle
ES20XX支持使用模板字符串跨越多行:
1 2 3 4 5 6 7 8 9 10 | let str = `This is a text with multiple lines. Escapes are interpreted, \ is a newline.`; let str = String.raw`This is a text with multiple lines. Escapes are not interpreted, \ is not a newline.`; |
1注意:缩小/模糊代码后会丢失
您可以在纯JavaScript中使用多行字符串。
此方法基于函数的序列化,函数被定义为依赖于实现。它在大多数浏览器中都能正常工作(见下文),但不能保证它将来仍能正常工作,所以不要依赖它。
使用以下功能:
1 2 3 4 5 | function hereDoc(f) { return f.toString(). replace(/^[^\\/]+\\/\\*!?/, ''). replace(/\\*\\/[^\\/]+$/, ''); } |
您可以在这里保存这样的文档:
1 2 3 4 5 | 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
- 火狐17-21(不在16-中)
- Rekonq 0.7.0-0.8.0
- konkeror 4.7.4不支持
不过,小心你的小奶头。它倾向于删除注释。对于yui压缩机,将保留以
我认为真正的解决办法是使用咖啡描述。
你可以这样做…
1 2 3 4 5 | var string = 'This is\ ' + 'a multiline\ ' + 'string'; |
我想出了一个非常吉米操纵的多行字符串方法。由于将函数转换为字符串也会返回函数内的任何注释,因此可以使用多行注释/**/将注释用作字符串。你只要把两端剪掉,你就有了绳子。
1 2 3 4 5 6 7 8 9 10 | var myString = function(){/* This is some awesome multi-lined string using a comment inside a function returned as a string. Enjoy the jimmy rigged code. */}.toString().slice(14,-3) alert(myString) |
我很惊讶我没有看到这一点,因为它在我测试过的任何地方都有效,而且对于模板非常有用:
1 2 3 4 5 6 7 | <script type="bogus" id="multi"> My multiline string alert($('#multi').html()); |
有人知道有HTML但它不起作用的环境吗?
我通过输出一个DIV,将其隐藏,并在需要时通过jquery调用DIV ID来解决这个问题。
例如
1 2 3 4 5 | Strings On Multiple Lines Here |
然后,当我需要获取字符串时,我只使用以下jquery:
1 | $('#UniqueID').html(); |
它返回多行的文本。如果我打电话
1 | alert($('#UniqueID').html()); |
我得到:
使用脚本标记:
- 将包含多行文本的
... 块添加到head 标记中; 按原样获取多行文本…(注意文本编码:UTF-8、ASCII)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25// pure javascript
var text = document.getElementById("mySoapMessage").innerHTML ;
// using JQuery's document ready for safety
$(document).ready(function() {
var text = $("#mySoapMessage").html();
});
<script id="mySoapMessage" type="text/plain">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="...">
<soapenv:Header/>
<soapenv:Body>
<typ:getConvocadosElement>
...
</typ:getConvocadosElement>
</soapenv:Body>
</soapenv:Envelope>
<!-- this comment will be present on your string -->
//uh-oh, javascript comments... SOAP request will fail
实现这一点有多种方法
1。斜线连接
1 2 3 4 5 6 7 8 9 | var MultiLine= '1\\ 2\\ 3\\ 4\\ 5\\ 6\\ 7\\ 8\\ 9'; |
2。规则连接
1 2 3 4 5 | var MultiLine = '1' +'2' +'3' +'4' +'5'; |
三。数组联接连接
1 2 3 4 5 6 7 | var MultiLine = [ '1', '2', '3', '4', '5' ].join(''); |
就性能而言,斜线连接(第一个)是最快的。
有关性能的更多详细信息,请参阅此测试用例
更新:
有了ES2015,我们可以利用它的模板字符串功能。有了它,我们只需要使用返回标记来创建多行字符串。
例子:
1 2 3 4 5 | `{{title}} {{hero.name}} details! <label>id: </label>{{hero.id}} <label>name: </label>{{hero.name}} ` |
我喜欢这样的语法和扩展:
1 2 3 4 5 | string = 'my long string...\ ' + 'continue here\ ' + 'and here.'; |
(但实际上不能视为多行字符串)
有一个图书馆使它美丽:
https://github.com/sindresorhus/multiline/多行
以前1 2 3 4 5 6 7 8 | var str = '' + '<!doctype html>' + '<html>' + ' <body>' + ' ? unicorns' + ' </body>' + '</html>' + ''; |
后
1 2 3 4 5 6 7 8 | var str = multiline(function(){/* <!doctype html> <html> <body> ? unicorns </body> </html> */}); |
反对者:此代码仅供参考。
这已经在Mac上的fx 19和chrome 24中进行了测试。
演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var new_comment; /*<<<EOF <li class="photobooth-comment"> <span class="username"> You </span> <span class="comment-text"> $text </span> <span class="comment-time"> 2d </span> </li> EOF*/ // note the script tag here is hardcoded as the FIRST tag new_comment=document.currentScript.innerHTML.split("EOF")[1]; alert(new_comment.replace('$text','Here goes some text')); |
综上所述,我尝试了用户javascript编程(opera 11.01)中列出的两种方法:
- 这个不起作用:在javascript中创建多行字符串
- 这非常有效,我还了解了如何在记事本+源代码视图中使其看起来更好:在javascript中创建多行字符串
所以我推荐Opera用户JS用户的工作方法。与作者所说的不同:
It doesn't work on firefox or opera; only on IE, chrome and safari.
它在歌剧11中起作用。至少在用户JS脚本中。太糟糕了,我不能对个别答案发表评论,也不能对答案投赞成票,我会立即这样做。如果可能的话,有更高权限的人请帮我做。
2015年更新:现在已经6年了:大多数人使用模块加载程序,而主模块系统都有加载模板的方法。它不是内联的,但是最常见的多行字符串类型是模板,而且模板通常应该远离JS。
require.js:"需要文本"。使用require.js"text"插件,在template.html中使用多行模板
1 | var template = require('text!template.html') |
npm/browserify:brfs模块
browserify使用"brfs"模块加载文本文件。这实际上会将您的模板构建到捆绑的HTML中。
1 2 | var fs = require("fs"); var template = fs.readFileSync(template.html', 'utf8'); |
容易的。
如果您愿意使用转义的换行符,它们可以很好地使用。它看起来像带有页面边框的文档。
它适用于IE、Safari、Chrome和Firefox:
1 2 3 4 5 6 7 8 | <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"> <tr> <td ><span class="mlayouttablecellsdynamic">PACKAGE price $65.00</span></td> </tr> </table>'> <script type="text/javascript"> alert($(".crazy_idea").attr("thorn_in_my_side")); |
我对https://stackoverflow.com/a/15558082/80404的扩展。它期望注释的形式为
1 2 3 4 5 6 7 8 9 10 | 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)); }; |
例子:
1 2 3 4 5 6 7 8 | var tmpl = function() { /*! <ul class="nav navbar-nav"> </ul> */}.extractComment(); |
javascript中的等效项是:
1 2 3 4 5 6 7 | var text = ` This Is A Multiline String `; |
这是规格。请参阅本页底部的浏览器支持。这里也有一些例子。
您可以使用typescript(javascript superset),它支持多行字符串,并在不增加开销的情况下返回到纯javascript:
1 2 3 4 5 6 7 | var templates = { myString: `this is a multiline string` } alert(templates.myString); |
如果您想用普通的javascript实现相同的功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 | var templates = { myString: function(){/* This is some awesome multi-lined string using a comment inside a function returned as a string. Enjoy the jimmy rigged code. */}.toString().slice(14,-3) } alert(templates.myString) |
注意ipad/safari不支持
如果您有很多遗留代码,还可以在typescript中使用普通的javascript变量(用于清除目的):
1 2 3 4 5 6 7 8 | interface externTemplates { myString:string; } declare var templates:externTemplates; alert(templates.myString) |
您可以使用纯javascript变量中的多行字符串对象,将模板放入另一个文件(可以合并到包中)。
您可以在
处尝试typescript。http://www.typescriptlang.org/操场
在javascrips中生成多行字符串的最简单方法是使用反勾号(``)。这允许您创建多行字符串,在其中可以使用
1 2 3 4 5 6 7 8 9 10 | let name = 'Willem'; let age = 26; let multilineString = ` my name is: ${name} my age is: ${age} `; console.log(multilineString); |
- 它是在
ES6 /es2015 中引入的。 - 现在所有主要浏览器供应商(Internet Explorer除外)都在本地支持它。
在这里检查Mozilla文档中的完全兼容性
ES6允许您使用反勾号在多行上指定字符串。它被称为模板文本。这样地:
1 2 3 4 | var multilineString = `One line of text second line of text third line of text fourth line of text`; |
在nodejs中使用backtick是可行的,它得到了chrome、firefox、edge、safari和opera的支持。
https://developer.mozilla.org/en-us/docs/web/javascript/reference/template_文本
你可以用
1 2 3 | var hello = 'hello' + 'world' + 'blah'; |
也可以写为
1 2 3 4 5 | var hello = 'hello'; hello += ' world'; hello += ' blah'; console.log(hello); |
还要注意,当在每行末尾使用前向反斜杠在多行上扩展字符串时,前向反斜杠后面的任何额外字符(主要是空格、制表符和错误添加的注释)都会导致意外的字符错误,我花了一个小时才发现
1 2 | var string ="line1\\ // comment, space or tabs here raise error line2"; |
为了热爱互联网,请使用字符串串联,并选择不使用ES6解决方案。ES6并不是全方位支持的,很像CSS3,某些浏览器在适应CSS3移动方面速度较慢。使用普通的ol'javascript,您的最终用户会感谢您。
例子:
"Once was lost will be found";
我的字符串concat基于数组的联接版本:
1 2 3 4 5 | var c = []; //c stands for content c.push(""); c.push(""); $(body).append(c.join('\ ')); |
这对我来说效果很好,特别是我经常在以这种方式构建的HTML中插入值。但它有很多局限性。压痕会很好。不必处理嵌套的引号将是非常好的,只是它的庞大困扰我。
要添加到数组中的.push()是否占用大量时间?请参阅相关答案:
(javascript开发人员不使用array.push()有什么原因吗?)
在查看了这些(相反的)测试运行之后,对于不太可能增长超过100个项的字符串数组来说,.push()是可以的-我将避免它,而倾向于为更大的数组添加索引。
必须使用串联运算符"+"。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> Document </head> <body> <p id="demo"> </p> var str ="This" +"\ is" +"\ multiline" +"\ string."; document.getElementById("demo").innerHTML = str; </body> </html> |
通过使用EDOCX1[1]您的源代码将看起来像-
1 2 3 4 | This is multiline string. |
通过使用
1 2 3 4 | This is multiline string. |
我认为这个解决方案应该适用于IE、Chrome、Firefox、Safari、Opera-
使用jQuery:
1 2 3 4 5 6 7 8 | <xmp id="unique_id" style="display:none;"> Some plain text Both type of quotes : " '" And '" ' JS Code : alert("Hello World"); HTML Code : </xmp> alert($('#unique_id').html()); |
使用纯javascript:
1 2 3 4 5 6 7 8 | <xmp id="unique_id" style="display:none;"> Some plain text Both type of quotes : " '" And '" ' JS Code : alert("Hello World"); HTML Code : </xmp> alert(document.getElementById('unique_id').innerHTML); |
干杯!!
ES6的方法是使用模板文本:
1 2 3 4 5 6 7 8 9 | const str = `This is a multiline text`; console.log(str); |
这里有更多参考资料
如果您碰巧只在节点中运行,那么可以使用fs模块从文件中读取多行字符串:
1 2 3 4 5 6 7 8 | var diagram; var fs = require('fs'); fs.readFile( __dirname + '/diagram.txt', function (err, data) { if (err) { throw err; } diagram = data.toString(); }); |
刚刚试过匿名答案,发现这里有一个小技巧,如果反斜杠后有一个空格,它就不起作用了
所以下面的解决方案不起作用-
1 2 3 | var x = { test:'<?xml version="1.0"?>\\ <-- One space here <?mso-application progid="Excel.Sheet"?>' }; |
但当空间被移除时,它会起作用。-
1 2 3 4 5 | var x = { test:'<?xml version="1.0"?>\\<-- No space here now <?mso-application progid="Excel.Sheet"?>' }; alert(x.test);? |
希望它有帮助!!
这是一种相当经济的方法,至少在源代码方面是如此:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function s() { var args = [],index; for (index = 0; index< arguments.length; index++) { args.push (arguments [index]); } return args.join ("\ "); } console.log (s ( "This is the first line", "and this is the second", "finally a third" )); function s() {return arguments.join ("\ ")} |
如果"arguments"属性是适当的数组,当然会更好。
第二个版本可能会使用"在您想要控制一个非常长的字符串中的换行符的情况下进行连接"。
我想我发现了另一种在每一行都没有任何侵入性语法的情况下进行内联的方法。使用javascript的功能将函数转换为字符串,并使用
1 2 3 4 5 6 7 8 9 10 11 | var multiline = function(string) { return string.toString().replace(/(^[^\ ]*\ )|(\ \\*\\/\\})/g,""); }; console.log(multiline(function() {/* Hello world! I'm a multiline string! Tada! */})); |
在这里我能看到的唯一陷阱是语法突出显示。
编辑:如果我再向下滚动一点,我会看到这个答案也在做同样的事情:https://stackoverflow.com/a/5571069/916553
我用这种方式编程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | sys = { layout: null, makeLayout: function (obCLS) { this.layout = $('').addClass('editor').appendTo($(obCLS)).append( /* Cargador */ /* @this.layout.find('> div:nth-of-child(1)'); */ '' + ' <p> Seleccione la imagen que desea procesar. </p>' + ' <input type="button" value="Seleccionar" class="btn btn-xlarge btn-success" />' + ' <span></span>' + '' + /* Cargador - Progreso */ /* @this.layout.find('> div:nth-of-child(2)'); */ '' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + '' + /* Editor */ /* @this.layout.find('> div:nth-of-child(3)'); * @sidebar = this.layout.find('> div:nth-of-child(3) > div > div > div:nth-of-type(1)'); * @body = this.layout.find('> div:nth-of-child(3) > div > div > div:nth-of-type(2) > div'); */ '' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + '' ); } } sys.makeLayout('#div'); |
我发现了一个更优雅的解决方案,可能与主题无关,因为它使用了PHP,但我相信它对你们中的一些人来说会很有用而且很可爱。
此javascript代码应保留在脚本标记内
1 2 3 4 5 6 7 8 9 10 11 12 | var html=<?php echo json_encode(" xxx ".$someVar." "); ?> |
在输出HTML中,您将看到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var html="\ \ \ \ \\t\\t\\t\ \ \\t\\t\\t\\t\ \ \\t\\t\\t\\t\\txxx\ \ \\t\\t\\t\\t<\\/div>\ \ \\t\\t\\t\\t\ \ \\t\\t\\t\\t\\t44\ \ \\t\\t\\t\\t<\\/div>\ \ \\t\\t\\t<\\/div>\ \ \ \ \\t\\t"; |
nbsp;
和ET Voice!,它使您在文件中具有代码可读性。
pd:这个示例使用json_encode()php函数,但是肯定有ASP、Ruby和JSP语言的函数等价物。
但是,这个解决方案也有他的局限性,其中之一是不能在封装的代码中使用javascript变量。
它不太优雅,但对我来说足够干净:
1 2 3 4 5 6 | var myString ="First line" +"\ "; var myString = myString +"Second line" +"\ "; var myString = myString +"Third line" +"\ "; |