Open6

タグ付きテンプレートリテラルを使ったメタプログラミング

HironHiron

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

function hello(){
  return 'Hello'
}

hello`goodby`

こんな感じで普通に関数を定義して、その後ろにテンプレートリテラルを置く。
この構文をタグ付きテンプレートリテラルと呼ぶ。

このタグ付きテンプレートリテラルの値は、関数の戻り値となる。
この構文を使うとバッククォートが、通常の関数呼び出しの丸括弧の代わりになる。

HironHiron

タグとなる関数は後ろのテンプレートリテラル全体を、関数の戻り値で置き換えてしまう。

function hello(){
  return 'Hello'
}

console.log(hello`goodbye`)
=> 'Hello'

console.log(hello`goodbye ${name}さん`)
=> 'Hello'

// 通常の関数呼び出しみたいに丸括弧で呼び出したのと同じ結果
console.log(hello(`goobye`))
=> 'Hello'

console.log(hello(`goodbye ${name}さん`))
=> 'Hello'
HironHiron

使い所

メタプログラミングが可能
HTMLやSQLのエスケープ処理をしたいときに使える

HironHiron

メタプログラミング

プログラムを使って全く別のプログラムを操作、生成、実行する by メタプログラミングRuby

コードを記述して、ほかのコードを操作する by オライリー JavaScript

HironHiron

普通の関数呼び出しとの違い

JavaScriptインタプリタがテンプレートリテラルを分解して、タグ関数の引数に渡してくれる

  • 第一引数 テンプレートリテラル内の文字列
  • 第二引数 テンプレートリテラル内の${}の部分

それぞれが配列となってタグ関数の引数に渡される

function checkArgs(args, ...rest){
  return { firstArg: args, secondArg: rest}
}

console.log(checkArgs`hello, ${'hiroto'}さん`)
=>
{
  firstArg: ["hello, ", "さん"],
  secondArg: ["hiroto"]
}

${}内に変数を渡すと"result"となって引数に渡される

console.log(checkArgs`hello, ${name}さん`)

{
  firstArg: ["hello, ", "さん"],
  secondArg: ["result"]
}

テンプレートリテラルを${}で終えた場合は第一引数の最後に空文字が入る。

console.log(checkArgs`hello, ${name}`)

{
  firstArg: ["hello, ", ""],
  secondArg: ["result"]
}
HironHiron

以下のように、for文でまわすと第一引数と、第二引数を順番に取り出すことができ、元のテンプレートリテラルを新しいものに変換できる。

function replecefooWithHoge(value){
  return value.replace('foo', 'hoge');
}

function Hoge(strings, ...values){
  result = ''
  for(let i=0;i < strings.length; i++){
    result += strings[i];
    if (i < strings.length - 1){
      result += replecefooWithHoge(values[i]);
    }
  }
  return result;
}
console.log(Hoge`${'hogefoohoge'}`)

同じ要領で、htmlの特殊文字をエスケープできたりする。

この手法がcommon-tagsというライブラリ(お手製のタグ関数を提供してくれるライブラリ)でも使われているらしい。