MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

模板源文本

翻譯不完整。請協助 翻譯此英文文件

模板源文本 (template literals) 是允許嵌入式語法的字串源文本 (string 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`

介紹

模板源文本使用 (` `) (重音符號,又稱反引號) 圍著,而非字串常用的、英文中的單引號或雙引號。模板源文本中可以包涵由錢字符($)與大括號({ })所構成的佔位符(即:${expression}),佔位符與其附近的文字會一併傳給函數,預設函數將把這些部分組合成一個單一的字串。如果模板源文本由一個表達式開頭(即下方範例中使用的 myTag),我們稱之為「帶標籤模板源文本」(tagged template literal)。在這種情況下,該標籤表達式(通常是函數)會在模板源文本處理後被呼叫,因此我們可以在輸出文字之前,做進一步的操作。若要在模板源文本中使用反引號,要使用轉義字元的形式,在前面加上反斜線「\」。

`\`` === '`' // --> 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
not ${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 "

  // 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

標籤函數不一定要回傳一個字串,如下列範例:

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`;
// logs "string text line 1 \n string text line 2" ,
// including the two characters '\' and '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 code point) 由 "\u{}" 作為開頭, 例: \u{2F804}
  • 十六進位制碼由 "\x" 作為開頭, 例: \xA9
  • 十進位制碼由 "\" 作為開頭, 例: \251

這表示像是下述的帶標籤模板源文本是有問題的,因為根據 ECMAScript 規範,一個語法分析器會嘗試以萬國碼轉義序列去解析它,然後發現序列有誤:

latex`\unicode`
// Throws in older ECMAScript versions (ES2016 and earlier)
// SyntaxError: malformed Unicode character escape sequence

Tagged template literals should allow the embedding of languages (for example DSLs, or LaTeX), where other escapes sequences are common. The ECMAScript proposal Template Literal Revision (stage 3, to be integrated in a future ECMAScript standard) removes the syntax restriction of ECMAScript escape sequences from tagged template literals.

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`;

規範

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.
Draft Defined in several section of the specification: Template Literals, Tagged Templates
Template Literal Revision Stage 3 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

更多相關

文件標籤與貢獻者

 此頁面的貢獻者: xsfishxs
 最近更新: xsfishxs,