String.raw()
String.raw() 静态方法是 模板字面量 的一个标签函数。这类似于 Python 中的 r 前缀,或 C# 中的 @ 前缀用于字符串字面量。它用于获取模板字面量的原始字符串形式 — 也就是说,替换(例如 ${foo})会被处理,但转义序列(例如 \n)则不会。
试一试
// Create a variable that uses a Windows
// path without escaping the backslashes:
const filePath = String.raw`C:\Development\profile\about.html`;
console.log(`The file was uploaded from: ${filePath}`);
// Expected output: "The file was uploaded from: C:\Development\profile\about.html"
语法
String.raw(strings)
String.raw(strings, sub1)
String.raw(strings, sub1, sub2)
String.raw(strings, sub1, sub2, /* …, */ subN)
String.raw`templateString`
参数
字符串-
格式正确的模板字面量数组对象,例如
{ raw: ['foo', 'bar', 'baz'] }。应该是一个具有raw属性的对象,其值是一个类数组对象,包含字符串。 sub1, …,subN-
包含替换值。
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.
在 RegExp 中使用 String.raw
将 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® 2026 语言规范 # sec-string.raw |
浏览器兼容性
加载中…