JS冷知识之不起眼但有用的String.raw方法
作者:掘金技术团队
String.raw
String.raw
是JavaScript中模板字符串的一个标签函数,它的作用是将模板字符串不转义的原始字符串内容返回。
也就是说,如下代码:
console.log(String.raw`Hi!\nAkira`);
将直接返回字符串 Hi!\nAkira
,而不是在Hi!
和Akira
中间插入回车。因为String.raw标签存在,所以\n
不被转义。这样其实相当于如下代码:
console.log(`Hi!\\nAkira`);
原始字符串不转义,在某些情况下很有用。不知道大家有没有遇到过用new RegExp
动态构建正则表达式的场景,比如下面的代码构建一个浏览器默认块级元素标签的正则匹配:
const blockTags = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul'; const blockReg = new RegExp(`(<\\s*(?:(?:\\/\\s*(?:${blockTags})\\s*)|(?:(?:${blockTags})\\s*\\/\\s*)|hr)>\\s*?)\\n`, 'ig');
在这里,因为我们使用了new RegExp
动态构建,所以我们就要把\s
替换成\\s
,把\/
替换成\\/
,把\n
替换成\\n
。但如果使用String.raw
,就可以不用这么替换,可以直接写成:
const blockReg = new RegExp(String.raw`(<\s*(?:(?:\/\s*(?:${blockTags})\s*)|(?:(?:${blockTags})\s*\/\s*)|hr)>\s*?)\n`, 'ig');
除了动态构建正则,还有输出或执行代码块的场景,比如:
const script = ` console.log('test \n test'); ` execScript(script);
上面这段代码执行会出错,因为\n
在字符串字面量中被替换成换行,导致实际执行的代码变成下面这样:
console.log('test test');
因为单引号字符串里面不能插入换行,所以上面的代码执行就报错了。
解决的办法是:
const script = String.raw` console.log('test \n test'); ` execScript(script);
这样就可以避免字符串代码的转义内容被解析。
所以,从上面可以看出,在字符串解析的场景下,String.raw
就会有用。比如我们要写一个使用KaTeX解析公式的React组件,我们希望这么使用:
<Katex macros={{...}}> 公式字符串 </Katex>
具体实现我们可以这样写:
import katex from 'katex'; import React from 'react'; import ReactDOM from 'react-dom'; const Katex = ({children, ...props}) => { const code = katex.renderToString(children, { ...props, throwOnError: false }) return ( <span dangerouslySetInnerHTML={{__html: code}}/> ) }
对于单行公式的解析没有问题
<Katex>x^2+y^2=1</Katex>
能够正确解析成:x2+y2=1x^2+y^2=1x2+y2=1
但是如果是多行公式:
<Katex macros={{"\\f": "#1f(#2)"}}> % \f is defined as #1f(#2) using the macro \f\relax{x} = \int_{-\infty}^\infty \f\hat\xi\,e^{2 \pi i \xi x} \,d\xi </Katex>
这么写是不行的,因为React在解析JSX的时候,会把内容中的回车去掉,空格合并,就像浏览器解析HTML标签那样,而且也不能正确处理转义符。所以如果像上面这么写,最后浏览器会报错。
这时候,我们就可以使用String.raw标签,将上面的代码写成下面这样:
<Katex macros={{"\\f": "#1f(#2)"}}>{String.raw` % \f is defined as #1f(#2) using the macro \f\relax{x} = \int_{-\infty}^\infty \f\hat\xi\,e^{2 \pi i \xi x} \,d\xi `}</Katex>
这样KaTeX就能正确解析字符串内容了,最终实现效果如下:
https://code.juejin.cn/pen/7106683225786810376
自定义标签
除了默认的String.raw,我们自定义的标签函数,也可以通过strings.raw来获得原始字符串内容,所以我们也可以将KaTeX公式解析定义成标签函数:
function KaTeX(strings, macros) { return katex.renderToString(strings.raw.join(''), { macros, throwOnError: false }); }
这样我们就可以通过标签函数来解析公式,再用React渲染出来:
https://code.juejin.cn/pen/7106726810817462286
以上就是全部内容,虽然很简单,但是非常有用。
你还知道或用过String.raw
以及其他标签函数吗?欢迎在评论区讨论。
到此这篇关于JS冷知识不起眼但有用的String.raw方法的文章就介绍到这了,更多相关javascript string.raw方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!