リテラル以外の文字列をタグに渡す
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ 文字列ひとつだけだと配列に入れて関数呼び出し
テンプレートストリングのタグは好きな処理ができるので String.raw のように文字列を返すものもあればオブジェクトを返すものもあります
オブジェクトの場合はメソッドを呼び出したり特定の関数に渡したり別のテンプレートに埋め込んだり様々な使い方ができます
タグによって作られるオブジェクトが欲しくても テンプレートストリングのタグはリテラル専用なので すでに変数に入っていると使えません
ただ タグと言ってもただの関数なので引数のフォーマットさえ合わせれば呼び出すだけで使えます
1つ目の引数に 文字列部分の配列が入り 2 つ目以降の引数に間に挟まる値が入ります
なので
これで動きます
もう少し挙動を合わせるための関数を作りました
使うときは
という感じです
リテラルではなく変数に入ってしまっているので raw 文字列は取得できません
しかし タグによっては raw の方を使うことがあるのでそのままの文字列を raw にも入れています
また 第一引数の配列はオブジェクトが固定されていて変更不可能であり 同じ場所のコードから作られたものは同じ参照になります
キャッシュさせることで同じ文字列なら同じオブジェクトになるようにしています
実際のタグでは同じ文字列でもコード上の別の場所なら別オブジェクトになりますが 文字列が同じなら同じオブジェクトで困ることはないと思います
const value = tag`123 ${123} 123`
value.xxx()
const value = tag`1, 2, 3`
const value2 = `aaa ${value} bbb`
オブジェクトの場合はメソッドを呼び出したり特定の関数に渡したり別のテンプレートに埋め込んだり様々な使い方ができます
タグによって作られるオブジェクトが欲しくても テンプレートストリングのタグはリテラル専用なので すでに変数に入っていると使えません
const str = "1, 2, 3"
// tag str <-- できない
ただ タグと言ってもただの関数なので引数のフォーマットさえ合わせれば呼び出すだけで使えます
1つ目の引数に 文字列部分の配列が入り 2 つ目以降の引数に間に挟まる値が入ります
なので
const value = tag([str])
value.xxx()
これで動きます
もう少し挙動を合わせるための関数を作りました
const cache = {}
export function passTag(tag, str){
if(!cache[str]){
const raw = [str]
Object.freeze(raw)
const arr = [str]
arr.raw = raw
Object.freeze(arr)
cache[str] = arr
}
return tag(cache[str])
}
使うときは
import { passTag } from "./pass-tag.js"
const value = passTag(tag, str)
value.xxx()
という感じです
リテラルではなく変数に入ってしまっているので raw 文字列は取得できません
しかし タグによっては raw の方を使うことがあるのでそのままの文字列を raw にも入れています
また 第一引数の配列はオブジェクトが固定されていて変更不可能であり 同じ場所のコードから作られたものは同じ参照になります
キャッシュさせることで同じ文字列なら同じオブジェクトになるようにしています
実際のタグでは同じ文字列でもコード上の別の場所なら別オブジェクトになりますが 文字列が同じなら同じオブジェクトで困ることはないと思います