バッククォートで囲むと値を埋め込め、改行もそのまま書けます。何を入れても文字列になること、オブジェクトが [object Object] になること、タグ付きテンプレートの仕組みまで実行して確かめます。
バッククォートで囲むと、${} の中に式を書けます。
example.js
const name = '猫';
const count = 3;
console.log(`${name}が${count}匹`);
console.log(`1 + 1 = ${1 + 1}`);
console.log(`1行目
2行目`);
出力書き換えて実行できます
猫が3匹
1 + 1 = 2
1行目
2行目
example.js
for (const value of [null, undefined, [1, 2], { a: 1 }, true]) {
console.log(`値: ${value}`);
}
出力書き換えて実行できます
値: null
値: undefined
値: 1,2
値: [object Object]
値: true
- 式が書けます。変数だけでなく計算も関数呼び出しも入ります
- 改行をそのまま書けます。
\n を書く必要はありません
何を入れても文字列になる
example.js
const missing = null;
console.log(`値: ${missing ?? '(未設定)'}`);
出力書き換えて実行できます
値: (未設定)
javascript
const user = { name: 'あ' };
console.log(`ユーザー: ${user}`);
ユーザー: [object Object]
null も undefined もそのまま文字になります。
「無いから空にしたい」なら、自分で書いてください。
example.js
const user = { name: 'あ' };
console.log(`ユーザー: ${JSON.stringify(user)}`);
出力書き換えて実行できます
ユーザー: {"name":"あ"}
example.js
const items = ['a', 'b'];
console.log(`<ul>${items.map((item) => `<li>${item}</li>`).join('')}</ul>`);
出力書き換えて実行できます
<ul><li>a</li><li>b</li></ul>
→ ?. と ??
オブジェクトは [object Object] になる
example.js
const count = 0;
console.log(`件数: ${count > 0 ? `${count}件` : 'なし'}`);
出力書き換えて実行できます
件数: なし
example.js
const name = 'あ';
const age = 20;
console.log('名前: ' + name + ' / 年齢: ' + age + '歳');
console.log(`名前: ${name} / 年齢: ${age}歳`);
出力書き換えて実行できます
名前: あ / 年齢: 20歳
名前: あ / 年齢: 20歳
ログに出したつもりで、中身が消えます。
見たいなら JSON.stringify() を挟んでください。
javascript
const price = 100;
console.log('合計: ' + price + 50 + '円');
console.log(`合計: ${price + 50}円`);
合計: 10050円
合計: 150円
example.js
function tag(strings, ...values) {
console.log(strings);
console.log(values);
return strings.raw.join('|');
}
const x = 1;
console.log(tag`a${x}b${x + 1}c`);
出力書き換えて実行できます
[ 'a', 'b', 'c' ]
[ 1, 2 ]
a|b|c
配列はカンマで繋がりますが、これも join() が呼ばれているだけです。
→ join() — 配列を1本の文字列にする
入れ子と条件
${} の中に、もう1つテンプレートリテラルを書けます。
example.js
function escapeHtml(strings, ...values) {
return strings.reduce((out, part, i) => {
if (i === 0) return part;
const escaped = String(values[i - 1]).replace(/</g, '<').replace(/>/g, '>');
return out + escaped + part;
}, '');
}
const input = '<script>';
console.log(escapeHtml`入力: ${input}`);
出力書き換えて実行できます
入力: <script>
example.js
console.log(String.raw`C:\new\table`);
console.log(`C:\new\table`.length);
出力書き換えて実行できます
C:\new\table
10
条件は三項演算子で書きます。
javascript
const query = `SELECT * FROM users WHERE name = '${input}'`;
if 文は書けません。 式だけです。
入れ子が2段を超えたら、先に変数へ出してください。 読めなくなります。
+ と比べて
結果は同じです。ですが + は、数と混ざったときに足し算になります。
混ぜるならテンプレートリテラルです。
→ 文字列の基本 — 作る・つなぐ・数える
タグ付きテンプレート
関数名をバッククォートの直前に書くと、分解された状態で受け取れます。
- 第1引数 …
${} で切られた文字の並び
- 第2引数以降 … 埋め込まれた値
必ず「文字・値・文字・値・文字」の順で、
文字のほうが1つ多くなります。
これを使うと、埋め込む値だけをまとめて加工できます。
これは仕組みを示すための最小の例です。実際の画面では、自分で組み立てず、枠組みの側の仕組みに任せてください。属性の中や URL の中では、必要な変換が違います。
String.raw
\ をそのままの文字として扱いたいときに使います。
String.raw を付けないと、\n は改行、\t はタブとして扱われます。
正規表現やファイルパスを書くときに効きます。
よくある間違い:SQL やコマンドを組み立てる
これはやらないでください。
input に ' が入るだけで壊れ、意図しない命令が混ざります。
文字列として組み立てるのではなく、値は値として渡す仕組みを使ってください。
テンプレートリテラルは見やすくするためのもので、安全にするものではありません。
まとめ
${} には式が書ける。改行はそのまま書ける
- 何を入れても文字列になる。
null も undefined もそのまま出る
- オブジェクトは
[object Object] に化ける。JSON.stringify() を挟む
+ と違い、数と混ざっても足し算にならない
- タグ付きにすると、文字の並びと埋めた値を分けて受け取れる
String.raw は \ をそのままにする
- SQL やコマンドを組み立てるのに使わない