◆ 配列だけど同じ参照
◆ オブジェクトがフリーズされてるので編集はできない
◆ 同じリテラルのテンプレートストリングから作られたことを簡単に判別できる

ライブラリのコードをみてた時になんでこうなるのか全然わからなくて調べてみたら驚きの動きでした

const tag = (strs, ...values) => strs

console.log(tag`(${1})`)
// ["(", ")", raw: Array(2)]

console.log(tag`(${1})` === tag`(${1})`)
// false

const a = []
for(let i = 0; i < 2; i++){
a.push(tag`(${1})`)
}
console.log(a[0] === a[1])
// true

const fn = () => tag`(${1})`
console.log(fn() === fn())
// true

const fn2 = (value) => tag`(${value})`
console.log(fn2(1) === fn2(2))
// true

template string のタグを使うと第一引数に渡される文字列部分の配列があります
配列なので毎回別のオブジェクトだと思っていたのですが 同じリテラルで作られた場合は同一のものです
同じ文字列でも別リテラルだと異なるものになります
文字列部分なので間に埋め込む値が異なっても関係なく同じになります

オブジェクトは参照になるので 要素を追加したり編集したら新しく作られるものにも影響しそうと思いましたが オブジェクトがフリーズされていて編集はできなくされていました

Object.isFrozen(fn())
// true

Object.getOwnPropertyDescriptors(fn())
// {}
// 0: {value: "(", writable: false, enumerable: true, configurable: false}
// 1: {value: ")", writable: false, enumerable: true, configurable: false}
// length: {value: 2, writable: false, enumerable: false, configurable: false}
// raw: {value: Array(2), writable: false, enumerable: false, configurable: false}

こういう特徴があるので 同じテンプレートストリングから作られたものかは簡単に判断できます