String.raw()

String.raw() 静态方法是 模板文字 的标记函数。这类似于 Python 中的 r 前缀,或 C# 中字符串文字的 @ 前缀。它用于获取模板文字的原始字符串形式 - 也就是说,处理替换(例如 ${foo}),但不处理转义序列(例如 \n)。

¥The String.raw() static method is a tag function of template literals. This is similar to the r prefix in Python, or the @ prefix in C# for string literals. It's used to get the raw string form of template literals — that is, substitutions (e.g. ${foo}) are processed, but escape sequences (e.g. \n) are not.

Try it

语法

¥Syntax

js
String.raw(strings)
String.raw(strings, sub1)
String.raw(strings, sub1, sub2)
String.raw(strings, sub1, sub2, /* …, */ subN)

String.raw`templateString`

参数

¥Parameters

strings

格式良好的模板文字数组对象,如 { raw: ['foo', 'bar', 'baz'] }。应该是一个具有 raw 属性的对象,其值是一个类似数组的字符串对象。

sub1, …, subN

包含替代值。

templateString

A 模板文字,可选地具有取代(${...})。

返回值

¥Return value

给定模板文字的原始字符串形式。

¥The raw string form of a given template literal.

例外情况

¥Exceptions

TypeError

如果第一个参数没有 raw 属性,或者 raw 属性是 undefinednull,则抛出该错误。

描述

¥Description

在大多数情况下,String.raw() 与模板文字一起使用。上面提到的第一种语法很少使用,因为 JavaScript 引擎会使用适当的参数来调用它(就像其他 标签功能 一样)。

¥In most cases, String.raw() is used with template literals. The first syntax mentioned above is only rarely used, because the JavaScript engine will call this with proper arguments for you, (just like with other tag functions).

String.raw() 是唯一的内置模板文字标记。它与未标记的文字具有接近的语义,因为它连接所有参数并返回一个字符串。你甚至可以使用普通的 JavaScript 代码重新实现它。

¥String.raw() is the only built-in template literal tag. It has close semantics to an untagged literal since it concatenates all arguments and returns a string. You can even re-implement it with normal JavaScript code.

警告:你不应直接使用 String.raw 作为 "identity" 标记。请参阅 构建身份标签 了解如何实现这一点。

¥Warning: You should not use String.raw directly as an "identity" tag. See Building an identity tag for how to implement this.

如果使用 raw 属性没有 length 属性或非正 length 的对象调用 String.raw(),则返回空字符串 ""。如果 substitutions.length < strings.raw.length - 1(即没有足够的替换来填充占位符 - 这在格式良好的标记模板文字中不会发生),则其余占位符将用空字符串填充。

¥If String.raw() is called with an object whose raw property doesn't have a length property or a non-positive length, it returns an empty string "". If substitutions.length < strings.raw.length - 1 (i.e. there are not enough substitutions to fill the placeholders — which can't happen in a well-formed tagged template literal), the rest of the placeholders are filled with empty strings.

示例

¥Examples

使用 String.raw()

¥Using String.raw()

js
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

¥Using String.raw with RegExp

String.raw 模板文字与 RegExp() 构造函数相结合,你可以创建具有动态部分的正则表达式(这在正则表达式文字中是不可能的),而无需双重转义(\\)正则表达式转义序列(这在普通字符串文字中是不可能的)。这在包含大量斜杠的字符串(例如文件路径或 URL)中也很有价值。

¥Combining a String.raw template literal with the RegExp() constructor allows you to create regular expressions with dynamic parts (which is not possible with regex literals) without double-escaping (\\) regular expression escape sequences (which is not possible with normal string literals). This is also valuable in strings that contain a lot of slashes, such as file paths or URLs.

js
// 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(".*");

构建身份标签

¥Building an identity tag

许多工具对用特定名称标记的文字进行特殊处理。

¥Many tools give special treatment to literals tagged by a particular name.

js
// 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 标签实现为:

¥One might naïvely implement the html tag as:

js
const html = String.raw;

事实上,这适用于上述情况。但是,由于 String.raw 将连接原始字符串文字而不是 "cooked" 字符串文字,因此不会处理转义序列。

¥This, in fact, works for the case above. However, because String.raw would concatenate the raw string literals instead of the "cooked" ones, escape sequences would not be processed.

js
const doc = html`<canvas>\n</canvas>`;
// "<canvas>\\n</canvas>"

这可能不是你想要的 "真实身份" 标记,该标记纯粹用于标记并且不会更改文字的值。在这种情况下,你可以创建一个自定义标记并将 "cooked"(即处理转义序列)文字数组传递给 String.raw,假装它们是原始字符串。

¥This may not be what you want for a "true identity" tag, where the tag is purely for markup and doesn't change the literal's value. In this case, you can create a custom tag and pass the "cooked" (i.e. escape sequences are processed) literal array to String.raw, pretending they are raw strings.

js
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

¥Notice the first argument is an object with a raw property, whose value is an array-like object (with a length property and integer indexes) representing the separated strings in the template literal. The rest of the arguments are the substitutions. Since the raw value can be any array-like object, it can even be a string! For example, 'test' is treated as ['t', 'e', 's', 't']. The following is equivalent to `t${0}e${1}s${2}t`:

js
String.raw({ raw: "test" }, 0, 1, 2); // 't0e1s2t'

规范

Specification
ECMAScript Language Specification
# sec-string.raw

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看