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コードを書いている限りは、この仕様を知らなくても大丈夫だと思います。