JavaScriptの''
、""
、``
は、どれも文字列を示す記号です。
この記事ではこれらの違い、そしてテンプレートリテラルについて紹介します。
''
と""
''
と""
は全く同じです。
記号が違うだけで、どちらも同じ文字列になります。
もちろん、===
で比較してみてもtrue
になります。
// trueになる
'Hello World!' === "Hello World!"
バッククォテーション(``)
``
を使うと、テンプレートリテラルという機能を使うことができます。
テンプレートリテラルでは、``
で囲った文字列の中に${}
を使うことで値を埋め込めます。
構文は大体こんな感じです。
console.log(`計算結果: ${10 + 20}`) // 10 + 20を埋め込む
// 計算結果: 30
例
例えば、以下のようにa
とb
の2つの変数があります。
const a = 10
const b = 20
ここでは、a + b
の計算結果である30
を、a + b = 30です
というフォーマットで出力してみます。
+
で繋げた場合
まずは比較用に、+
で数値と文字列を繋げた例を紹介します。
console.log("a + b = " + (a + b) + "です")
(a + b)
の()
を省くと出力結果が変わってしまいます。
このコードでは+
を2つの目的で使用しています。
- 文字列と数値を繋げて文字列にする
- 数値と数値を足し算する
そのため、+
が何の役割を果たすのかわかりづらくなってしまっています。
これは主観ですが、このようなコードは少し読みづらいです。
テンプレートリテラルを使う場合
先ほどのコードは、テンプレートリテラルを使うと以下のように書けます。
console.log(`a + b = ${a + b}です`)
どうでしょうか。読みやすいと思いませんか?
もし今思わなくても、慣れてきたらこちらのほうが読みやすいと感じるはずです。たぶん。
先ほどのコードもこのコードも、実行結果は全く同じです。
そのため好きなほうを使えばいいのですが、どうせ使うなら読みやすいほうを使いたくないですか?
この記法を使うと、以下のようにコードが読みやすくなります。
-
+
がコードから消えるので、この+
の役割は何?を考える必要がなくなる- 代わりの
${}
は、少なくとも$
がコードに出てくる機会はほぼない
- 代わりの
- ハイライトがわかりやすく、どの部分が文字列でないのか直感的にわかる
それ以外の特徴
``
で囲った文字列は、''
や""
と比べてほかにも以下の特徴があります。
- 複数行の文字列が書ける
- タグ付きテンプレートという構文が使える
詳細はMDNをご覧ください。
JavaScriptの文字列
ということで、ここからはJavaScriptの文字列について解説していきます。
前提として、文字列は''
、""
、``
で囲むことで作成できます。
文字列はconsole.log
でログに出力したり、変数に代入したりできます。
また、文字列はstring
型と呼ばれることもあります。
プリミティブ
JavaScriptの文字列はプリミティブです。
プリミティブはオブジェクトでない値のことで、文字列や数値、真偽値などがあります。
プリミティブには以下のような仕様があります。
- メソッドはないが呼び出せる
- 不変(イミュータブル)
詳細はMDNをご覧ください。
値で比較される
===
演算子を使った比較では、文字列の参照ではなく値が同じかどうかで比較されます。
"abc" === "abc" // true
参照とは
反対に、オブジェクトは参照で比較されます。
ここでオブジェクトと呼ばれるものは、例えばこんなものがあります。
- 配列
- オブジェクトリテラル(
{}
を使って作ったオブジェクト) -
Map
やSet
など
参照とは何かを正確に説明する能力は筆者にはないので、ざっくりとした解説になります。
参照とは簡単に言うと、値の場所を保持しておく値のようなものです。
参照はオブジェクトごとに一意です。
追記 2024/12/4
ECMAScriptの仕様書を読んでみたところ、比較はおよそこのような感じになっていそうでした。
- identityというものがある
- identityがない値(Values without identity)がある
- number / bigInt / string / null / undefined / boolean
- これらはidentityで比較されないが、比較の際に参照を使う(ここの
Let lRef be ? Evaluation of EqualityExpression.
のあたり)
- identityを持つ値(value with identity)がある
- Object / Symbol(例外:
Symbol.for
) - これらはidentityで比較される
- Object / Symbol(例外:
@juner ありがとうございました!
普通にJavaScriptを書いている限り、参照の実態を直接見る機会はありません。
配列やオブジェクトリテラルは参照で比較されます。
参照はオブジェクトごとに一意なので、中身が同じでも参照が異なればfalse
を返します。
const array1 = [1, 3, 5]
const array2 = [1, 3, 5]
array1 === array2 // false
メソッドが呼び出せる
文字列はメソッドが呼び出せます。
メソッドには様々なものがあり、例えば文字列の中に別の文字列が含まれるかどうかを返すincludes
があります。
const str = 'Hello World!'
console.log(str.includes('Hello')) // true
console.log(str.includes('Hi!')) // false
全てのメソッドはMDNから見ることができます。
暇なときにでも眺めてみると、どんなメソッドがあるかが知れておすすめです。
実は、プリミティブにメソッドはありません。
ではなぜ上でメソッドが呼び出せたかというと、自動でラッパーオブジェクトが作られるからです。
例えば文字列のラッパーオブジェクトはString
オブジェクトです。
文字列のメソッドを呼び出そうとすると、文字列プリミティブは自動でString
オブジェクトに変換されます。
そして、そのラッパーオブジェクトに対してメソッドが呼び出されます。
なお、普通にJavaScriptコードを書いている限りは、この仕様を知らなくても大丈夫だと思います。