JS冷知识之不起眼但有用的String.raw方法

目录
  • 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就能正确解析字符串内容了,最终实现效果如下:

自定义标签

除了默认的String.raw,我们自定义的标签函数,也可以通过strings.raw来获得原始字符串内容,所以我们也可以将KaTeX公式解析定义成标签函数:

function KaTeX(strings, macros) {
  return katex.renderToString(strings.raw.join(''), {
    macros,
    throwOnError: false
  });
}

这样我们就可以通过标签函数来解析公式,再用React渲染出来:

以上就是全部内容,虽然很简单,但是非常有用。

你还知道或用过String.raw以及其他标签函数吗?欢迎在评论区讨论。

到此这篇关于JS冷知识不起眼但有用的String.raw方法的文章就介绍到这了,更多相关javascript string.raw方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • web3.js增加eth.getRawTransactionByHash(txhash)方法步骤

    eth_getRawTransactionByHash https://ethereum.stackexchange.com/questions/7473/get-raw-transaction-from-hash There is an "undocumented" method eth_getRawTransactionByHash from JSON-RPC curl -H "Content-Type: application/json" -X POST --

  • crawler4j抓取页面使用jsoup解析html时的解决方法

    crawler4j对已有编码的页面抓取效果不错,用jsoup解析,很多会jquery的程序员都可以操作.但是,crawler4j对response没有指定编码的页面,解析成乱码,很让人烦恼.在找了苦闷之中,无意间发现一年代已久的博文,可以解决问题,修改 Page.load() 中的 contentData 编码即可,这让我心中顿时舒坦了很多,接下来的问题都引刃而解了. 复制代码 代码如下: public void load(HttpEntity entity) throws Exception

  • JS冷知识之不起眼但有用的String.raw方法

    目录 String.raw 自定义标签 String.raw String.raw是JavaScript中模板字符串的一个标签函数,它的作用是将模板字符串不转义的原始字符串内容返回. 也就是说,如下代码: console.log(String.raw`Hi!\nAkira`); 将直接返回字符串 Hi!\nAkira,而不是在Hi!和Akira中间插入回车.因为String.raw标签存在,所以\n不被转义.这样其实相当于如下代码: console.log(`Hi!\\nAkira`); 原始字

  • Python中关于浮点数的冷知识

    本周的PyCoder's Weekly 上分享了一篇小文章,它里面提到的冷知识很有意思,我稍作补充,分享给大家. 它提到的部分问题,读者们可以先思考下: 若两个元组相等,即 a==b 且 a is b,那么相同索引的元素(如 a[0] .b[0])是否必然相等呢? 若两个对象的 hash 结果相等,即 hash(a) == hash(b),那么它们是否必然相等呢? 答案当然都为否(不然就不叫冷知识了),大家可以先尝试回答一下,然后再往下看. -----思考分割线----- 好了,先来看看第一个问

  • node.js基础知识汇总

    一.node介绍 1.node的应用场景 工具类 gulp webpack vite (node可以让js运行在服务器) 可以做服务端 优化ssr 可以做中间层 (解决跨域问题,格式化数据) 2.性能 非阻塞 异步I/O(当这个方法调用完毕后不会立即返回结果) 事件驱动(发布订阅模式) 3.优势 在Java.PHP或者.NET等服务器语言中,会为每一个客户端连接创建一个新的线程.而每个线程需要耗费大约2MB内存.也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右.要

  • C语言冷知识之预处理字符串操作符详解

    目录 在C语言中什么是标记 预处理字符串操作符 #字符串化操作符 ##标记(Token)连接操作符 当年学习C语言的第一门课就提到过标记(Token)的概念,不过,相信在多年之后你再次听到这个术语时会一脸懵逼,比如我. 因此特地翻了翻资料,整理下来这些笔记. 在C语言中什么是标记 标记是编程语言处理的基本单元,也叫最小划分元素,比如关键字.操作符.变量名.函数名.字符串.数值等等. 下面举例说明一下: printf("hello world!"); 对上面的语句进行标记划分,可分为5个

  • JS通过调用微信API实现微信支付功能的方法示例

    本文实例讲述了JS通过调用微信API实现微信支付功能的方法.分享给大家供大家参考,具体如下: 最近在做微信公众号开发,在微信支付上遇到一些问题,困惑了3天,今天终于搞定.期间要感谢一些大神的帮助,趁热下面分享一下我的经验. 在实现微信支付之前,需要到微信开发平台认证,这些认证和配置信息我就不多说了,这里主要从代码层面实现支付. function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId&quo

  • js获取当前页的URL与window.location.href简单方法

    利用JavaScript获取当前页的URL,这个问题起来好像很复杂,如果第一次去想这个问题,很多人估计又在琢磨到底又是哪个神一般的Javascript函数. 其实不是,Javascript获取当前页的URL的函数就是我们经常用来重定向的window.location.href. 比如如下函数: <script> var url=window.location.href; var loc = url.substring(url.lastIndexOf('/')+1, url.length); a

  • JS自定义对象实现Java中Map对象功能的方法

    本文实例讲述了JS自定义对象实现Java中Map对象功能的方法.分享给大家供大家参考.具体分析如下: Java中有集合,Map等对象存储工具类,这些对象使用简易,但是在JavaScript中,你只能使用Array对象. 这里我创建一个自定义对象,这个对象内包含一个数组来存储数据,数据对象是一个Key,可以实际存储的内容!   这里Key,你要使用String类型,和Java一样,你可以进行一些增加,删除,修改,获得的操作. 使用很简单,我先把工具类给大家看下: 复制代码 代码如下: /**  *

  • js实现统计字符串中特定字符出现个数的方法

    本文实例讲述了js实现统计字符串中特定字符出现个数的方法.分享给大家供大家参考,具体如下: //js统计字符串中包含的特定字符个数 function getPlaceholderCount(strSource) { //统计字符串中包含{}或{xxXX}的个数 var thisCount = 0; strSource.replace(/\{[xX]+\}|\{\}/g, function (m, i) { //m为找到的{xx}元素.i为索引 thisCount++; }); return th

  • JS模态窗口返回值兼容问题的完美解决方法

    因系统要兼容原IE已使用的关闭方法,经调试测得,需对window.dialogArguments进行再较验,不然易出问题. function OKEnd(vals) { if (vals == null) vals = "TRUE"; if (typeof (window.opener) == "undefined") { if (typeof (window.dialogArguments) != "undefined") { if (wind

  • js实现a标签超链接提交form表单的方法

    本文实例讲述了js实现a标签超链接提交form表单的方法.分享给大家供大家参考.具体实现方法如下: <form action="/home/search" method="get" id="search_form"> <div class="searchBox png" id="searchBox"> <input type="text" id="

随机推荐