はじめに
こんにちは。
JavaScriptの比較演算子では、数値だけでなく文字列の比較も行うことができます。
この記事では、文字列同士が比較される基準や、数値と文字列を比較した場合の挙動などについて調べたことをまとめました。
文字列同士はUTF-16コード単位で比較される
JavaScriptでは、数値だけでなく文字列にも <、>、<=、>= といった比較演算子を使うことができます。
文字列同士を比較した場合、一般的な辞書順ではなくUTF-16コード単位の値に基づいて比較されます。
UTF-16コード単位は、JavaScriptが文字列を扱うときの内部的な単位です。
多くの文字は1つのUTF-16コード単位で表されますが、絵文字など一部の文字は2つのUTF-16コード単位で表されます。
下記のコードで試してみましょう。
console.log("a" < "b");
実行結果は次のようになります。
true
a はUTF-16コード単位では 0x0061、b は 0x0062 になるのでこのような結果となります。
また、アルファベットの場合小文字より大文字の方がUTF-16コード単位の値が小さいです。同じアルファベットの大文字と小文字を比較する例を見てみましょう。
console.log("A" < "a");
実行結果は次のようになります。
true
いろいろな文字で比較してみる
ひらがな、カタカナ、記号、漢字、絵文字でも同じように比較できます。
console.log("あ" < "い");
console.log("ア" < "あ");
console.log("ぁ" < "あ");
console.log("!" < "0");
console.log("一" < "二"); //漢数字の1と2
console.log("😀" < "😃");
この例の場合、実行結果は次のようになります。
true
false
true
true
true
true
それぞれのUTF-16コード単位を表にすると、次のようになります。
| 文字 | UTF-16コード単位 |
|---|---|
| ! | 0x0021 |
| 0 | 0x0030 |
| A | 0x0041 |
| a | 0x0061 |
| ぁ | 0x3041 |
| あ | 0x3042 |
| い | 0x3044 |
| ア | 0x30A2 |
| 一 | 0x4E00 |
| 二 | 0x4E8C |
| 😀 | 0xD83D 0xDE00 |
| 😃 | 0xD83D 0xDE03 |
また、文字ごとのUTF-16コード単位は、charCodeAt() で確認できます。
charCodeAt() はUTF-16コード単位を10進数で返しますが、toString(16) で16進数に変換することができます。
console.log("A".charCodeAt(0).toString(16));
console.log("😀".charCodeAt(0).toString(16));
console.log("😀".charCodeAt(1).toString(16));
実行結果は次のようになります。
41
d83d
de00
長さが違う文字列を比較するとどうなる?
長さの違う文字列同士を比較する場合、まず先頭の文字から順番に比較され、違う文字が出た時点で結果が決まります。
次のコードで確認してみましょう。
console.log("A" < "AA");
console.log("B" < "AA");
実行結果は次のようになります。
true
false
"A" < "AA" は、途中まで同じで片方だけ続きがあるため、短い "A" の方が小さい扱いになります。
一方で、"B" < "AA" はfalseになります。これは文字数ではなく、先頭の "B" と "A" の比較で結果が決まるためです。
数値を文字列として比較する
中身が数値であっても、両方が文字列として扱われていれば文字列として比較されます。
console.log("10" < "2");
実行結果は次のようになります。
true
数値として見ると10は2より大きいですが、先頭の "1" と "2" のUTF-16コード単位の値が比較され、"1" の方が小さいため true になります。
一方で、片方を数値として扱っている場合は挙動が変わります。
console.log("10" < 2);
実行結果は次のようになります。
false
この場合、"10" は数値に変換され、10と2の数値比較になります。
そのため、10 < 2 はfalseです。
数値にできない文字列と数値の比較
数値にできない文字列を数値と比較する例を試してみます。
console.log("hello" < 5);
console.log(5 < "hello");
実行結果は次のようになります。
false
false
"hello" は数値に変換できないため、NaN として扱われます。
比較対象のどちらかが NaN になる場合、結果はfalseになります。
まとめ
- JavaScriptでは、文字列にも
<や>などの比較演算子を使える - 両方が文字列の場合、UTF-16コード単位の値 に基づいて比較される
- 文字列は先頭から順に比較される
-
"10" < "2"のような場合は文字列として比較されるが、"10" < 2のような場合は"10"が数値に変換され、数値として比較される
お読みいただきありがとうございました。