テンプレート文字列

Template literal は組み込み式を扱うことができる文字列リテラルです。複数行文字列や文字列内挿機能を使用できます。

ES2015 仕様の以前のエディションでは、"template strings" と呼ばれていました。

構文

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag`string text ${expression} string text`

説明

Template literal は、ダブルクオートやシングルクオートの代わりにバックティック文字 (` `) (グレイヴ・アクセント) で囲みます。

Template literal にはプレースホルダーを含めることができます。プレースホルダーはドル記号と波括弧 (${expression}) で示されます。プレースホルダー内の式とバックティック文字 (` `) の間にあるテキストは関数に渡されます。

既定の関数はパーツを 1 つの文字列として繋げるだけです。template literal の前に式がある場合、template literal は タグ付けされた template literal と呼ばれます。この場合、タグ式 (通常は関数) は、template literal と一緒に呼び出され、アウトプットの前に実行できます。

template literal 内でバックティック文字をエスケープするためには、バックティック文字の前にバックスラッシュ (\) を置きます。

`\`` === '`' // --> true

複数行文字列

ソースに挿入されたあらゆる改行文字列は、template literal に含まれます。

通常の文字列を使うと、複数行文字列を取得するために次の構文を使用しないといけません:

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"

式内挿法

通常の文字列に式を内挿するために、あなたは次のような構文を使用するでしょう:

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

Template literalを使用すれば、このようにもっと読みやすくするシンタックスシュガーを使うことができます:

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

ネストしたテンプレートリテラル

場合によっては、ネストしたテンプレートリテラルの方が読みやすい場合があります。バックチックとテンプレートリテラルを、${ } プレースホルダーの中で単に使用するだけです。

例えば、条件式が true の場合、このテンプレートリテラルを return します。

ES5 の場合:

let classes = 'header';
classes += (isLargeScreen() ?
   '' : item.isCollapsed ?
     ' icon-expander' : ' icon-collapser');

ES2015 でネストせずにテンプレートリテラルで書いた場合:

const classes = `header ${ isLargeScreen() ? '' :
    (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;

ES2015 でネストしたテンプレートリテラルで書いた場合:

const classes = `header ${ isLargeScreen() ? '' :
 `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;

タグ付けされたTemplate literal

Template literal のより高度な使用法は タグ付けされた Template literal です。

タグを使用すると、テンプレートリテラルを関数で解析できます。タグ関数の最初の引数には、文字列リテラルの配列を含みます。残りの引数は式に関連しています。

タグ関数は、これらの引数に対して任意の処理を実行し、うまく加工した文字列を返してくれます。(または、次の例の 1 つで示されているように、まったく異なる値を返すこともできます。)

タグに使用される関数の名前は、自由に指定できます。

let person = 'Mike';
let age = 28;

function myTag(strings, personExp, ageExp) {
  let str0 = strings[0]; // "That "
  let 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];

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

  // We can even return a string built using a template literal
  return `${str0}${personExp}${str1}${ageStr}`;
}

let output = myTag`That ${ person } is a ${ age }`;

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

タグ関数は文字列を返す必要さえありません!

function template(strings, ...keys) {
  return (function(...values) {
    let dict = values[values.length - 1] || {};
    let result = [strings[0]];
    keys.forEach(function(key, i) {
      let value = Number.isInteger(key) ? values[key] : dict[key];
      result.push(value, strings[i + 1]);
    });
    return result.join('');
  });
}

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

Raw strings

タグ関数に渡される第 1 引数では、特別な raw プロパティが利用できます。このプロパティを通し、エスケープシーケンスが処理されていない状態の、入力された通りの生の文字列を参照できます。

function tag(strings) {
  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() というメソッドがあります。デフォルトテンプレート関数のように動作し、生の文字列の状態で文字列の連結を行います。

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

str.length;
// 6

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

タグ付けされたテンプレートとエスケープシーケンス

ES2016 での振る舞い

ECMAScript 2016 時点では、タグ付けされたテンプレートの以下のエスケープシーケンスには、次のようなルールが適用されます:

  • Unicode のエスケープシーケンスは "\u" で始まること。例: \u00A9
  • Unicode のコードポイントのエスケープは "\u{}" で示すこと。例: \u{2F804}
  • 16 進数のエスケープは "\x" で始まること。例: \xA9
  • 8 進数のリテラルのエスケープは "\0o" で始まり、その後数字が続くこと。例: \0o251

このルールのもとでは、下に示す例のようなタグ付けされたテンプレートが問題となります。なぜなら、ECMAScript の文法に従ってこのテキストを解釈しようとすると、パーサーは Unicode の有効のエスケープシーケンスを探そうとするも、不正な構文が検出されてしまうからです。

latex`\unicode`
// 古い ECMAScript バージョン (ES2016 以前) では、以下のような例外が投げられる
// SyntaxError: malformed Unicode character escape sequence

ES2018 revision での不正なエスケープシーケンス

タグ付きテンプレートでは、他のエスケープシーケンスが一般的な言語 (DSLLaTeX など) の埋め込みも許容する必要があります。ECMAScript プロポーザル Template Literal Revision (Stage 4, to be integrated in the ECMAScript 2018 standard) では、タグ付きテンプレートから、ECMAScript のエスケープシーケンスについての構文的な制約が除外されています。

しかし、埋め込んで “加工された (cooked)” 結果の中においても、不正なエスケープシーケンスがあれば、それを提示する必要があります。こうした不正なエスケープシーケンスは、“加工された” の配列の中では、undefined な要素として表示されます。

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

latex`\unicode`

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

このエスケープシーケンスの制約は、タグ付き テンプレートのみが除外となります。タグ付きでない テンプレートリテラルの場合は、除外対象ではありません:

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

仕様

仕様
ECMAScript (ECMA-262)
Template Literals の定義
ECMAScript (ECMA-262)
Tagged templates Literals の定義

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
Template literalsChrome 完全対応 41Edge 完全対応 12Firefox 完全対応 34IE 未対応 なしOpera 完全対応 28Safari 完全対応 9WebView Android 完全対応 41Chrome Android 完全対応 41Firefox Android 完全対応 34Opera Android 完全対応 28Safari iOS 完全対応 9Samsung Internet Android 完全対応 4.0nodejs 完全対応 4.0.0
Escape sequences allowed in tagged template literals
実験的
Chrome 完全対応 62Edge 完全対応 79Firefox 完全対応 53IE 未対応 なしOpera 完全対応 49Safari 完全対応 11WebView Android 完全対応 62Chrome Android 完全対応 62Firefox Android 完全対応 53Opera Android 完全対応 46Safari iOS 完全対応 11Samsung Internet Android 完全対応 8.0nodejs 完全対応 8.10.0

凡例

完全対応  
完全対応
未対応  
未対応
実験的。動作が変更される可能性があります。
実験的。動作が変更される可能性があります。

関連項目