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.
Syntax
String.raw(strings)
String.raw(strings, sub1)
String.raw(strings, sub1, sub2)
String.raw(strings, sub1, sub2, /* …, */ subN)
String.raw`templateString`
Parameters
strings
- : Well-formed template literal array object, like
{ raw: ['foo', 'bar', 'baz'] }
. Should be an object with araw
property whose value is an array-like object of strings.
- : Well-formed template literal array object, like
sub1
, …,subN
- : Contains substitution values.
templateString
- : A template literal, optionally with substitutions (
${...}
).
- : A template literal, optionally with substitutions (
Return value
The raw string form of a given template literal.
Exceptions
- TypeError
- : Thrown if the first argument doesn't have a
raw
property, or theraw
property isundefined
ornull
.
- : Thrown if the first argument doesn't have a
Description
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()
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.
Warning: You should not use
String.raw
directly as an "identity" tag. See Building an identity tag for how to implement this.
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
Using 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.
Building an identity tag
Many tools give special treatment to literals tagged by a particular name.
// 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>
`;
One might naïvely implement the html
tag as:
const html = String.raw;
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.
const doc = html`<canvas>\n</canvas>`;
// "<canvas>\\n</canvas>"
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.
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
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`
:
String.raw({ raw: "test" }, 0, 1, 2); // 't0e1s2t'