【クイズでわかる】JavaScriptの文字コードとUnicodeの仕組み|lengthがバグる理由も解説!

こんにちは!Reiです‎(˵ •̀ ᴗ – ˵) ✧


入力欄に表示されている文字数と、実際に入力した文字数が合わない…

なんて経験、1度はあると思います 👀


たとえばこれ↓

const str = "𩸽";
console.log(str.length);

見た目は1文字なのに、結果は「2」になります。

パッと見だとちょっと不思議ですよね〜 (*꒪꒫꒪)ホェー


このあたりで出てくるのが、
「Unicode」や「UTF-16」といった文字コードのの仕組み。


今回は、クイズ形式でコードの動きを確認しながら、
JavaScriptの文字の扱いについて見ていきます。

どんな動きになるのか、ぜひ考えながら見てみてください ᥫᩣ ̖́-


第1問 変数名に使える文字(識別子とUnicode)

まずはここから!

const name = "Taro";
const 名前 = "たろう";
const 🐈 = "cat";

このコードを実行したとき、エラーにならないのはどれでしょうか?

  1. nameだけ
  2. name と 名前
  3. すべてOK

正解は… (ここをクリック!)

2の「name と 名前」です。
つまり、絵文字はエラーになります!
(簡単だったかな?)


解説 !!

ここで出てくるのが「識別子」と「Unicode」。


「識別子」とは、変数名や関数名などの名前のこと。

そして「Unicode」は、世界中の文字を扱うためのルール。
ざっくり言うと、世界中の文字に番号を割り振る仕組みです。


たとえばこんな感じ↓

“A” → U+0041
“あ” → U+3042

このように、それぞれの文字には番号が決まっています 👀

JavaScriptはこのUnicodeをもとにして、
「識別子として使える文字」を判断しているのです。

なので、

const 名前 = "たろう";

のように、識別子を日本語にしても問題なく使えるんです!


一方で、

const 🐈 = "cat";

はエラーになってしまいます 💦

日本語は「文字」として扱われるため変数名に使えますが、
絵文字は「記号」や「装飾的な文字」として扱われるため、変数名には使えません。


ポイントとしては、

・ JavaScriptはUnicodeベースで動いている
・ 日本語は識別子として使える
・ 絵文字は記号に該当するので使えない

という点です。
覚えておくと意外と便利かも?


第2問 Unicodeエスケープシークエンス

次はこちら!

console.log("\u3042");

これを実行するとどうなるでしょうか?

  1. \u3042 と表示される
  2. あ と表示される
  3. エラーになる

正解は… (ここをクリック!)

2の「あ」でした!


解説 !!

これは「Unicodeエスケープ」という書き方です。

さっき出てきたUnicodeの「文字の番号」を使って、
文字を表現しています!


実際の変換はこんな感じ↓

“\u3042” → “あ”
“\u0041” → “A”

つまり、文字を直接書いているのではなく、
番号で指定しているです!


ちょっとイメージしにくいですが、
「文字そのものではなく、対応する番号を書いている」という感じです。


この方法は、

・文字化けを防ぎたいとき
・特殊な文字を扱いたいとき

とかに使われます!

普段はあまり意識しない部分ですが、
こういった書き方があると頭の片隅に置いておくと良いかも!


第3問 lengthの挙動

最後の問題はこちら!

const str = "𩸽";
console.log(str.length);

さて、どうなるでしょうか!

  1. 1になる
  2. 2になる
  3. 4になる

正解は… (ここをクリック!)

「2になる」でした!
(ここが一番ややこしいポイントかも!)


解説 !!

JavaScriptはUnicodeで文字を扱っていますが、
内部では「UTF-16」という形式で管理しています。


UTF-16とは、文字を一定のサイズに区切って扱うためのルールのこと。

ざっくり言うと、

・多くの文字 → 1つで表現
・一部の文字 → 2つで表現

するという仕組みです。

この「2つで1文字を表す仕組み」を サロゲートペア と呼びます。


今回の「𩸽」は、
この「2つで表現する文字」に当たります 👀

イメージするとこんな感じ↓

"𩸽" → ["パーツ1", "パーツ2"]

なので、str.length で文字数を取得する際に、
見た目の文字数ではなく内部で分かれている数を数えてしまうため、文字数が 2 としてカウントされてしまうのです。


補足💡 文字数を正しく数えるには?
[...str].length
このようにして文字を数えると、文字を1つずつ分解してから数えているため、
内部では2つに分かれていた文字が、1つのまとまりとして扱われます。


ここまでのポイントおさらい !!

今回の内容をまとめると、次のとおり↓

Unicode

  • 文字に番号を割り振る仕組み
  • JavaScriptはUnicodeをもとに動いている

識別子

  • 変数名や関数名のこと
  • Unicodeに基づいて使える文字が決まっている
  • 日本語は使えるが、絵文字は使えない

文字列の長さ

  • lengthは文字数ではなく、UTF-16で分割された数で数えている
  • サロゲートペアの文字は、文字が2つ分としてカウントされる

今回の内容は少し細かい部分ではありますが、

・文字数のカウント
・入力チェック
・バリデーション

などでズレが出る原因になることがあります。

このあたりを知っておくだけでも、
思っていた結果と違う、というケースはかなり減るはずです 💡


最後に

JavaScriptの文字は、見たままの1文字として扱われているわけではなく、
内部の仕組みによって処理されています。

今回のように、

・Unicode
・UTF-16
・lengthの挙動

このあたりをちょっぴり意識して見てみると、
コードの見え方が少し変わってくるかもしれません。

少しでも参考になっていたら嬉しいです ᥫᩣ ̖́-

コメント

タイトルとURLをコピーしました