タグ関数についてまとめてみた

2 min read

タグ関数とは

HTMLのテンプレートを引数に渡す目的で実装された関数のことです。
以下のコードでは、tagFunction がタグ関数に該当します。

const view = tagFunction`
	 <div>${hoge}${fuga}</div>
`;

function tagFunction(strings, ...values) {
	console.log(strings);
	console.log(...values);
}

タグ関数について調べた背景

JSPrimerでタグ関数を学習していた際、
上記のようなタグ関数の引数をコンソールに出力した際に、配列が出力された

第一引数(strings) の出力結果

0: "↵ <div>
1: "と"
2: "</div>↵"

第二引数(...values) の出力結果

hoge fuga

この時

Q. どういうルールで、第一引数に入る配列が作成されるのか

Q. タグ関数を呼び出す際、引数にはHTMLテンプレート1つしか渡していないのに、第二引数に値が入るのはなぜか

という疑問を持ったので、調べてみました。

タグ関数の呼び出し方

タグ関数を呼び出す時は、通常の関数と違い

関数`テンプレート`;

という書き方をします。

一般的な関数呼び出しは

関数(引数); 

と書きます。

使い方

実際のコードだと以下のように使います。
escapeHTML がタグ関数に該当します。

const view = escapeHTML`
	 <h4>${userInfo.name} (@${userInfo.login})</h4>
	 <img src="${userInfo.avatar_url}" alt="${userInfo.login}" height="100">
	 <dl>
	   <dt>Location</dt>
	   <dd>${userInfo.location}</dd>
	   <dt>Repositories</dt>
	   <dd>${userInfo.public_repos}</dd>
	 </dl>
`;

function escapeHTML(strings, ...values) {
  return strings.reduce((result, str, i) => {
    const value = values[i - 1];
    if (typeof value === "string") {
      return result + escapeSpecialChars(value) + str;
    } else {
      return result + String(value) + str;
    }
  });
}

userInfoの定義

githubのユーザ情報が格納されており、各プロパティの詳細は以下の通りです。

userInfo.name:ユーザ名
userInfo.login:ログイン名
userInfo.avatar_url:プロフィール画像
userInfo.location:住んでいる国名
userInfo.public_repos:パブリックリポジトリの数

それでは、背景で書いた疑問の解答を書いていきます。

疑問1つ目

Q. どういうルールで、HTMLのテンプレートが区切られて、配列へ格納されるのか
A. テンプレートリテラル内の${value}が区切りとなり、それぞれが一要素として配列へ格納されます

配列をコンソールに出力すると、以下が表示されました。

(7) ["↵             <h4>", " (@", ")</h4>↵             <img src="", "" alt="", "" height="100">↵             <dl>↵               <dt>Location</dt>↵               <dd>", "</dd>↵               <dt>Repositories</dt>↵               <dd>", "</dd>↵             </dl>↵          ", raw: Array(7)]
0: "↵             <h4>"
1: " (@"
2: ")</h4>↵             <img src=""
3: "" alt=""
4: "" height="100">↵             <dl>↵               <dt>Location</dt>↵               <dd>"
5: "</dd>↵               <dt>Repositories</dt>↵               <dd>"
6: "</dd>↵             </dl>↵          "

疑問2つ目

Q. タグ関数を呼び出す際、引数にはHTMLテンプレート1つしか渡していないのに、第二引数に値が入るのはなぜか
A. valuesには、テンプレートリテラル内の${value}の実際の値が格納された配列が入るため

第二引数(...values) もコンソールに出力すると、以下が表示されました。

null "bita-kodai" "プロフィール画像のURL" "bita-kodai" null 17

終わりに

最後までご覧頂きありがとうございます。

何か補足や疑問点、フィードバック等々ございましたら、コメント欄への記載をお願いします。