首頁 > 軟體

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

2022-06-08 22:00:44

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
frelax{x} = int_{-infty}^infty
    fhatxi,e^{2 pi i xi x}
    ,dxi
</Katex>

這麼寫是不行的,因為React在解析JSX的時候,會把內容中的回車去掉,空格合併,就像瀏覽器解析HTML標籤那樣,而且也不能正確處理跳脫符。所以如果像上面這麼寫,最後瀏覽器會報錯。

這時候,我們就可以使用String.raw標籤,將上面的程式碼寫成下面這樣:

<Katex macros={{"\f": "#1f(#2)"}}>{String.raw`
% f is defined as #1f(#2) using the macro
frelax{x} = int_{-infty}^infty
    fhatxi,e^{2 pi i xi x}
    ,dxi
`}</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方法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com