翻译正在进行中。

 

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

语法

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`

Note: 模板字面量也可以使用三元运算符( condition ?  true : false ) 和嵌套

描述

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

`\`` === "`" // --> true

多行字符串

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

console.log("string text line 1\n\
string text line 2");
// "string text line 1
// string text line 2"

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

console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"

表达式插补

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

var a = 5;
var b = 10;
console.log("Fifteen is " + (a + b) + " and\nnot " + (2 * a + b) + ".");
// "Fifteen is 15 and
// not 20."

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

var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."

带标签的模板字符串


更高级的形式的模板字符串是带标签的模板字符串。标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其余的参数与表达式相关。最后,你的函数可以返回处理好的的字符串(或者它可以返回完全不同的东西 , 如下个例子所述)。用于该标签的函数的名称可以被命名为任何名字。

var person = 'Mike';
var age = 28;

function myTag(strings, personExp, ageExp) {

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

  // 在技术上,有一个字符串在
  // 最终的表达式 (在我们的例子中)的后面,
  // 但它是空的(""), 所以被忽略.
  // var str2 = strings[2];

  var ageStr;
  if (ageExp > 60){
    ageStr = 'old person';
  } else {
    ageStr = 'young person';
  }

  return str0 + personExp + str1 + ageStr;

}

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

console.log(output);    // that Mike is a young person
//show函数采用rest参数的写法如下:

let name = '张三',

    age = 20,

    message = show`我来给大家介绍:${name}的年龄是${age}.`;

function show(stringArr,...values){

let output ="";

let index = 0

    for(;index<values.length;index++){

        output += stringArr [index]+values[index];

    }

    output += stringArr [index];

    return output;

}

message;       //"我来给大家介绍:张三的年龄是20."

正如下面例子所展示的,标签函数并不一定需要返回一个字符串。

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 ,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。

function tag(strings, ...values) {
  console.log(strings.raw[0]); 
}

tag`string text line 1 \n string text line 2`;
// 输出 "string text line 1 \n string text line 2",
// 将会包括包含 '\' 和 'n' 这两个字符(即不经过任何转义的原生字符串)

另外,使用String.raw() 方法创建原始字符串和使用默认模板函数和字符串连接创建是一样的。

var str = String.raw`Hi\n${2+3}!`;
// "Hi\n5!"

str.length;
// 6

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

 

带标签的模版字面量及转义序列

自ES2016起,带标签的模版字面量遵守以下转义序列的规则:

  • Unicode字符以"\u"开头,例如\u00A9
  • Unicode码位用"\u{}"表示,例如\u{2F804}
  • 十六进制以"\x"开头,例如\xA9
  • 八进制以"\"和数字开头,例如\251

这表示类似下面这种带标签的模版是有问题的,因为对于每一个ECMAScript语法,解析器都会去查找有效的转义序列,但是只能得到这是一个形式错误的语法:

latex`\unicode`
// 在较老的ECMAScript版本中报错(ES2016及更早)
// SyntaxError: malformed Unicode character escape sequence

 

ES2018关于非法转义序列的修订

 

带标签的模版字符串应该允许嵌套支持常见转义序列的语言(例如DSLsLaTeX)。ECMAScript提议模版字面量修订(第4阶段,将要集成到ECMAScript 2018标准) 移除对ECMAScript在带标签的模版字符串中转义序列的语法限制。

However, illegal escape sequence must still be represented in the "cooked" representation. They will show up as undefined element in the "cooked" array:

function latex(str) { 
 return { "cooked": str[0], "raw": str.raw[0] }
} 

latex`\unicode`

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

Note that the escape sequence restriction is only dropped from tagged template literals and not from untagged template literals:

let bad = `bad escape sequence: \unicode`;

规范

规范 状态 说明
ECMAScript 2015 (6th Edition, ECMA-262)
Template Literals
Standard Initial definition. Defined in several section of the specification: Template LiteralsTagged Templates
ECMAScript Latest Draft (ECMA-262)
Template Literals
Draft Defined in several section of the specification: Template LiteralsTagged Templates

浏览器兼容

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 41 34 (34) 12/Edge (modern.ie) 28 9
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 未实现 41.0 34.0 (34) 未实现 28 9

See also

文档标签和贡献者

 最后编辑者: pujiaxun,