首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Template literals

模板字面量/Template literals 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。它们在ES2015规范的先前版本中被称为“模板字符串/template strings”。

句法

代码语言:javascript
复制
`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`

描述

模板字符串使用反引号 (` `) 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。

代码语言:javascript
复制
`\`` === '`' // --> true

多行字符串

在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:

代码语言:javascript
复制
console.log('string text line 1\n' +
'string text line 2');
// "string text line 1
// string text line 2"

要获得同样效果的多行字符串,只需使用如下代码:

代码语言:javascript
复制
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"

表达式插补

在普通字符串中嵌入表达式,必须使用如下语法:

代码语言:javascript
复制
var a = 5;
var b = 10;
console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
// "Fifteen is 15 and
// not 20."

现在通过模板字符串,我们可以使用一种更优雅的方式来表示:

代码语言:javascript
复制
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."

嵌套模板

在某些时候,嵌套模板是最简单也是更可读的方式来配置字符串。在一个被抽出的模板中,简单地通过${( )}在模板中添加括号来允许内部反引号。例如,如果条件是真的,那么返回这个模板化的文字。

In ES5:

代码语言:javascript
复制
var classes = 'header'
classes += (isLargeScreen() ?
   '' : item.isCollapsed ?
     ' icon-expander' : ' icon-collapser');

在ES2015中使用模板文字而不嵌套:

代码语言:javascript
复制
const classes = `header ${ isLargeScreen() && item.isCollapsed ?
    'icon-expander' : 'icon-collapser' }`;

In ES2015 with nested template literals:

代码语言:javascript
复制
const classes = `header ${( isLargeScreen() &&
 `icon-${item.isCollapsed ? 'expander' : 'collapser'}`)}`;

标记模板文字

A more advanced form of template literals are tagged template literals. Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions. In the end, your function can return your manipulated string (or it can return something completely different as described in the next example). The name of the function used for the tag can be named whatever you want.

代码语言:javascript
复制
var person = 'Mike';
var age = 28;

function myTag(strings, personExp, ageExp) {

  var str0 = strings[0]; // "that "
  var str1 = strings[1]; // " is a "

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

  var ageStr;
  if (ageExp > 99){
    ageStr = 'centenarian';
  } else {
    ageStr = 'youngster';
  }

  return str0 + personExp + str1 + ageStr;

}

var output = myTag`that ${ person } is a ${ age }`;

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

标记函数不需要返回字符串,如下例所示。

代码语言:javascript
复制
function template(strings, ...keys) {
  return (function(...values) {
    var dict = values[values.length - 1] || {};
    var result = [strings[0]];
    keys.forEach(function(key, i) {
      var value = Number.isInteger(key) ? values[key] : dict[key];
      result.push(value, strings[i + 1]);
    });
    return result.join('');
  });
}

var t1Closure = template`${0}${1}${0}!`;
t1Closure('Y', 'A');  // "YAY!"
var t2Closure = template`${0} ${'foo'}!`;
t2Closure('Hello', {foo: 'World'});  // "Hello World!"

原始字符串

raw标记模板文字的第一个函数参数上的特殊属性允许您在输入时访问原始字符串,而不处理转义序列

代码语言:javascript
复制
function tag(strings, ...values) {
  console.log(strings.raw[0]);
}

tag`string text line 1 \n string text line 2`;
// logs "string text line 1 \n string text line 2" ,
// including the two characters '\' and 'n'

此外,该String.raw()方法存在创建原始字符串就像默认的模板函数和字符串连接会创建。

代码语言:javascript
复制
var str = String.raw`Hi\n${2+3}!`;
// "Hi\n5!"

str.length;
// 6

str.split('').join(',');
// "H,i,\,n,5,!"

标记模板文字和转义序列

从ES2016开始,标记的模板字面符合以下转义序列的规则:

  • Unicode escapes started by "\u", for example \u00A9
  • Unicode code point escapes indicated by "\u{}", for example \u{2F804}
  • Hexadecimal escapes started by "\x", for example \xA9
  • Octal literal escapes started by "\" and (a) digit(s), for example \251

这意味着像下面这样的标记模板是有问题的,因为根据ECMAScript语法,解析器查找有效的Unicode转义序列,但发现格式错误的语法:

代码语言:javascript
复制
latex`\unicode`
// Throws in older ECMAScript versions (ES2016 and earlier)
// SyntaxError: malformed Unicode character escape sequence

标记的模板文字应该允许嵌入语言(例如DSLLaTeX),其他转义序列是常见的。ECMAScript提议模板文字修订(阶段4,将被集成到ECMAScript 2018标准中)从标签模板文字中删除ECMAScript转义序列的语法限制。

但是,非法转义序列仍然必须以“熟”的表示来表示。它们将undefined在“熟化”数组中显示为元素:

代码语言:javascript
复制
function latex(str) { 
 return { "cooked": str[0], "raw": str.raw[0] }
} 

latex`\unicode`

// { cooked: undefined, raw: "\\unicode" }

请注意,转义序列限制仅从标记的模板文字中删除,而不是从未标记的模板文字中删除:

代码语言:javascript
复制
let bad = `bad escape sequence: \unicode`;

产品规格

Specification

Status

Comment

ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'Template Literals' in that specification.

Standard

Initial definition. Defined in several section of the specification: Template Literals, Tagged Templates

ECMAScript Latest Draft (ECMA-262)The definition of 'Template Literals' in that specification.

Living Standard

Defined in several section of the specification: Template Literals, Tagged Templates

Template Literal Revision

Stage 4 draft

Drops escape sequence restriction from tagged template literals

浏览器兼容性

Feature

Chrome

Edge

Firefox (Gecko)

Internet Explorer

Opera

Safari

Basic support

41

(Yes)

34 (34)

No support

28

9

Template Literal Revision

No support

No support

53 (53)

No support

No support

No support

Feature

Android

Chrome for Android

Firefox Mobile (Gecko)

IE Mobile

Opera Mobile

Safari Mobile

Basic support

No support

41

34.0 (34)

No support

28

9

Template Literal Revision

No support

No support

53.0 (53)

No support

No support

No support

扫码关注腾讯云开发者

领取腾讯云代金券