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

こちらの記事は以下の書籍を参考に執筆しました

- [入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)

#タグ付きテンプレートリテラルとは
関数を使ってタグ付けしたテンプレートリテラルのことです。
#タグ付のやり方
テンプレートリテラルの先頭にその関数の名前を配置します。

```javascript
myTag`my string`
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)


上の例では`my string`を関数`myTag`でタグ付けしています。
**`myTag`関数の呼び出しではテンプレートリテラルが引数として渡されます。**

テンプレートリテラルを関数でタグ付けすると、テンプレートリテラルが**文字列部分と補間部分に分解**され、タグ関数に別々の引数として渡されます。

|引数|説明|
|---|---|
|最初の引数|文字列部分がすべて含まれた配列|
|以降の引数|補間される値|

```javascript
function tagFunction(
stringPartsArray,
interpolatedValue1,
...,
interpolatedValueN)
{

}
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)


**しかしこれらの引数を明示的に記述する必要はありません。**
##テンプレートリテラルが分解されて関数に渡される仕組み

これらの要素が分解されて関数に渡される仕組みを知るために以下の例を見てみましょう。

```javascript
function logParts() {
  let stringParts = arguments[0];
  let values = [].slice.call(arguments, 1)
  console.log('Strings', stringParts)
  console.log('Values', values)
}

logParts `1${2}3${4}${5}`;
//Strings:["1", "3", "", "", raw: Array(4)]
//Values:[2, 4, 5]
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)


上記では`arguments`オブジェクトを使って文字列部分と補間される値を解析しています。
>**arguments** は、関数へ渡された引数を含む、関数内のみアクセス可能な 配列様 (Array-like) オブジェクトです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/arguments

`let stringParts = arguments[0];`
で最初の引数を取得しています。

`  let values = [].slice.call(arguments, 1)`
で2つ目以降のパラメータがすべて含まれた配列を取得しています。
**argumentsオブジェクト**は配列ではなく配列風オブジェクトです。配列風オブジェクトを配列にするには`[].slice,call()`を実行します。

>arguments オブジェクトは Array ではありません。これは Array と似ていますが、length 以外のどんな Array のプロパティも持ちません。たとえば、これは pop メソッドを持ちません。しかしながら、これは本当の Array に変換できます。

Stringsに文字列`'1'`と`'3'`のあと、空文字が含まれていますが、これは4と5の間に補間される値が隣り合わせで、間に他の文字列部分が含まれていない場合、それらの間には空の文字列が存在していると解釈されるためです。
**これは文字列の先頭と末尾にも当てはまります。**

```
//----------------------------
//文字列   "1"   "3"   ""   ""
//値          2     4    5
//----------------------------
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)



このため常に最初と最後の要素は文字列で、値はそれらをつなぎ合わせる存在です。
**つまり単純なreduce関数でそれらの値を処理できるということです。**

```javascript
function noop(){
let stringParts=arguments[0];
let values=[].slice.call(arguments,1)
return stringParts.reduce(function(memo,nextParts){
  //shiftメソッドは配列から最初の値を取り出す。
  return memo+String(values.shift())+nextParts
})
}
noop`1${2}3${4}${5}`;//12345
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)