String.raw()
String.raw()
静态方法是 模板字面量 的标签函数。这类似于 Python 中的 r
前缀,或 C# 中字符串字面量的 @
前缀。它用于获取模板字面量的原始字符串形式——也就是说,替换(例如 ${foo}
)会被处理,但转义序列(例如 \n
)不会。
试一试
语法
String.raw(strings)
String.raw(strings, sub1)
String.raw(strings, sub1, sub2)
String.raw(strings, sub1, sub2, /* …, */ subN)
String.raw`templateString`
参数
返回值
给定模板字面量的原始字符串形式。
异常
TypeError
-
如果第一个参数没有
raw
属性,或者raw
属性为undefined
或null
,则抛出此异常。
描述
在大多数情况下,String.raw()
与模板字面量一起使用。上面提到的第一个语法很少使用,因为 JavaScript 引擎会为您调用此方法并传递正确的参数(就像其他 标签函数 一样)。
String.raw()
是唯一的内置模板字面量标签。它与未标记的字面量具有相似的语义,因为它连接所有参数并返回一个字符串。您甚至可以使用普通的 JavaScript 代码重新实现它。
警告:您不应将 String.raw
直接用作“标识”标签。有关如何实现此目的,请参阅 构建标识标签。
如果 String.raw()
被调用时,其 raw
属性没有 length
属性或其 length
为非正数,则返回空字符串 ""
。如果 substitutions.length < strings.raw.length - 1
(即没有足够的替换来填充占位符——这在格式良好的标记模板字面量中不可能发生),则其余的占位符将填充空字符串。
示例
使用 String.raw()
String.raw`Hi\n${2 + 3}!`;
// 'Hi\\n5!', the character after 'Hi'
// is not a newline character,
// '\' and 'n' are two characters.
String.raw`Hi\u000A!`;
// 'Hi\\u000A!', same here, this time we will get the
// \, u, 0, 0, 0, A, 6 characters.
// All kinds of escape characters will be ineffective
// and backslashes will be present in the output string.
// You can confirm this by checking the .length property
// of the string.
const name = "Bob";
String.raw`Hi\n${name}!`;
// 'Hi\\nBob!', substitutions are processed.
String.raw`Hi \${name}!`;
// 'Hi \\${name}!', the dollar sign is escaped; there's no interpolation.
将 String.raw 与 RegExp 一起使用
将 String.raw
模板字面量与 RegExp()
构造函数结合使用,您可以创建具有动态部分的正则表达式(这在正则表达式字面量中是不可能的),而无需双重转义(\\
)正则表达式转义序列(这在普通字符串字面量中是不可能的)。这在包含大量斜杠的字符串(例如文件路径或 URL)中也很有价值。
// A String.raw template allows a fairly readable regular expression matching a URL:
const reRawTemplate = new RegExp(
String.raw`https://developer\.mozilla\.org/en-US/docs/Web/JavaScript/Reference/`,
);
// The same thing with a regexp literal looks like this, with \/ for
// each forward slash:
const reRegexpLiteral =
/https:\/\/developer\.mozilla\.org\/en-US\/docs\/Web\/JavaScript\/Reference\//;
// And the same thing written with the RegExp constructor and a
// traditional string literal, with \\. for each period:
const reStringLiteral = new RegExp(
"https://developer\\.mozilla\\.org/en-US/docs/Web/JavaScript/Reference/",
);
// String.raw also allows dynamic parts to be included
function makeURLRegExp(path) {
return new RegExp(String.raw`https://developer\.mozilla\.org/${path}`);
}
const reDynamic = makeURLRegExp("en-US/docs/Web/JavaScript/Reference/");
const reWildcard = makeURLRegExp(".*");
构建标识标签
许多工具对由特定名称标记的字面量进行特殊处理。
// Some formatters will format this literal's content as HTML
const doc = html`<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
`;
有人可能会天真地将 html
标签实现为
const html = String.raw;
实际上,这在上述情况下有效。但是,由于 String.raw
会连接原始字符串字面量而不是“已处理”的字符串字面量,因此不会处理转义序列。
const doc = html`<canvas>\n</canvas>`;
// "<canvas>\\n</canvas>"
对于“真正的标识”标签,这可能不是您想要的,其中标签纯粹用于标记并且不会更改字面量的值。在这种情况下,您可以创建一个自定义标签并将“已处理”(即已处理转义序列)的字面量数组传递给 String.raw
,假装它们是原始字符串。
const html = (strings, ...values) => String.raw({ raw: strings }, ...values);
// Some formatters will format this literal's content as HTML
const doc = html`<canvas>\n</canvas>`;
// "<canvas>\n</canvas>"; the "\n" becomes a line break
请注意,第一个参数是一个对象,它具有一个 raw
属性,其值是一个类似数组的对象(具有 length
属性和整数索引),表示模板字面量中分隔的字符串。其余参数是替换。由于 raw
值可以是任何类似数组的对象,因此它甚至可以是字符串!例如,'test'
被视为 ['t', 'e', 's', 't']
。以下是 `t${0}e${1}s${2}t`
的等效项
String.raw({ raw: "test" }, 0, 1, 2); // 't0e1s2t'
规范
规范 |
---|
ECMAScript 语言规范 # sec-string.raw |
浏览器兼容性
BCD 表格仅在浏览器中加载