简体   繁体   中英

How do tagged template literals work in JavaScript?

Consider the following snippet:

let a = (x) => console.log(x);
a`1234`; // prints "Array [ "1234" ]"

Why does the string, following the variable holding the anonymous function, makes the function run passing itself in an Array as argument? Is there any documentation reference for this behavior?

Also, why it doesn't work when using quotes or double quotes for declaring the string literal?

Tagged template literals take the form of (strings: string[], ...values: any[]): any .

In your example,

let a = (x) => console.log(x);
a`1234`; // prints "Array [ "1234" ]"

x has the type string[] , which is an array of all non-interpolated strings (basically anything that's not inside ${} ). Because there are no interpolations, the array contains one element (the string "1234"). This is what is passed as the first argument to your function a .

Only template literals can be "tagged" with a function identifier, which is why you've noticed that it doesn't work with single or double-quoted strings, only backticks. I presume it would throw a syntax error if you tried to do it with a regular string, though I haven't tested that.

If you wanted to interpolate a value, you'd do so by receiving the value in the function (which is used as the tag) by adding additional parameters. Note that it is not a single parameter that is an array, but rather separate parameters. You can, of course, create an array from them by using the spread operator ( ... ), as indicated in the function signature above. As in the (modified) example provided by MDN,

const person = 'Mike';
const age = 28;

function tag(strings, person, age) {
  const str0 = strings[0]; // "That "
  const str1 = strings[1]; // " is a "

  // There is technically a string after
  // the final expression (in our example),
  // but it is empty (""), so disregard.
  // const str2 = strings[2];

  const age_description = age > 99 ? 'centenarian' : 'youngster';
  return [str0, name, str1, ageDescription].join('');
}

const output = tag`That ${person} is a ${age}`;

console.log(output); // "That Mike is a youngster"

Note that as indicated in the comments, there is always a leading and trailing string, even if it happens to be empty. As such, if you began a template literal with an interpolation, strings[0] would be an empty string. In the same manner, ending with an interpolation leaves a trailing empty string, though this isn't as notable (a leading interpolation shifts all indexes by one, a trailing doesn't affect them).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM