【JavaScript】いまさらだけどテンプレートリテラルを理解する

JavaScript

はじめに

JavaScriptにはテンプレートリテラルと呼ばれるものがあります。このテンプレートリテラル、とくにタグ付きテンプレートリテラルと呼ばれるものについて理解が薄かったので、まとめてみました。

テンプレートリテラル

テンプレートリテラルはECMAScript 2015にて導入された、バッククォート(`)で区切られたリテラルです。中に式を埋め込んだり、エスケープシーケンスを使うことなく改行を直接埋め込んだりできます。文字列に似た形をしていますが、必ずしも文字列になるとは限りません。

使い方

前述の通り、テンプレートリテラルはバッククォートでくくります。バッククォートでくくっただけのテンプレートリテラルをタグ無しテンプレートリテラルとも呼びます。

const str = `JavaScript`;

この結果は文字列となります。また、以下のように改行を直接含めることもできます。

const str2 = `JavaScript
Python
C++`;

テンプレートリテラルにはプレースホルダを含めることができます。プレースホルダは${}で表され、カッコの中には式を指定します。

const value = "JavaScript";
const str3 = `I learn ${value}!`; // str3 = "I learn JavaScript!"

テンプレートリテラルを使うと、文字列を+で連結する必要がなくなり、簡潔に表現することができるようになります。

タグ付きテンプレートリテラル

タグ付きテンプレートリテラルとは、テンプレートリテラルのより高度な形式(MDNより)です。テンプレートリテラルに対しタグ関数と呼ばれる関数を作用させ、何らかの処理を行うことができます。タグ関数は必ずしも文字列を返す必要はありません。

タグ関数の定義

タグ関数は通常の関数と同じように定義できます。

function tag(templates, ...expressions) {
  ...
}

タグ関数は複数の引数を取ることができ、第一引数は文字列リテラルの配列です。それ以降は、${}で囲まれた式を評価した値が順番に渡されます(...expressions...に続けて引数を指定した場合は配列として受け取ることができます)。どのように引数が渡されるかは、次の例を御覧ください。

function showArguments(templates, ...expressions) {
  console.log("templates = ");
  console.log(templates);
  console.log("expressions = ");
  console.log(expressions);
}

showArguments`あああ${1}いいい${2}ううう${"3" + "1"}えええ${true}おおお${2 + 3}`;

出力結果

templates = 
[ 'あああ', 'いいい', 'ううう', 'えええ', 'おおお', '' ]
expressions = 
[ 1, 2, '31', true, 5 ]

第一引数(templates)の方には、プレースホルダの前後の文字列が分割されて配列として渡されます。この例のように最後がプレースホルダで終わっている場合には、空の文字列が最後の要素となります。第二引数以降(expressions)には、${}で囲まれた式が処理された結果が渡されます。

rawプロパティ

第一引数には特別なプロパティがあります。それがrawプロパティです。rawプロパティはエスケープシーケンスを処理する前の生の文字列を保持しています。

function showRaw(templates) {
  console.log("templates[0] =");
  console.log(templates[0]);
  console.log("templates.raw[0] =");
  console.log(templates.raw[0]);
}

showRaw`This\nis\na\npen.`;

出力結果

templates[0] =
This
is
a
pen.
templates.raw[0] =
This\nis\na\npen.

この例では、エスケープシーケンスの\n(改行)が含まれたテンプレートリテラルを扱っています。templates[0] では、この\nが改行として処理されています。一方、templates.raw[0]では、ただ単に文字列\nとして扱われています。

使用例

タグ付きテンプレートリテラルの使用例として、プレースホルダに渡される文字列を加工する例を示します。この例では、プレースホルダに渡される文字列中の<, >&lt;, &gt;に置き換えます。

function escapeTag(templates, ...expressions) {
  let result = templates[0];

  for (let i = 0, len = expressions.length; i < len; i++) {
    const str = expressions[i].replace(/\</g, "&lt;").replace(/\>/g, "&gt;");
    result += str + templates[i + 1];
  }

  return result;
}

const inputs = ["JavaScript", "<Python>", "C++"];
console.log(escapeTag`1: ${inputs[0]}, 2: ${inputs[1]}, 3: ${inputs[2]}`);

出力結果

1: JavaScript, 2: &lt;Python&gt;, 3: C++

まとめ

JavaScriptにおけるテンプレートリテラルについてまとめてみました。とくに他の言語では馴染みのない書き方をするタグ付きテンプレートリテラルについて、タグ関数の書き方や動作を学ぶことで理解を深めることができました。

JavaScript

Posted by izadori