6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2021年12月9日 JavaScript (JS Primer) 文字列とUnicode

Code PointとCode Unitの違い

インデックス 0 1 2 3 4
文字列 🍎
UnicodeのCode Point(16進数) 0x30ea 0x30f3 0x30b4 0x1134e
UTF-16のCode Unit(16進数) 0x30ea 0x30f3 0x30b4 0xd83c 0xdf4e
  • Code Unitは絵文字を表すのに1つのIDでは表現しきれない2つのIDで表します。
  • Code Pointでは一意なIDで表現できます。

primerの説明がとてもわかりやすかったので引用させていただきます。

ある1つの文字に対応するIDであるCode Pointを、16ビット(2バイト)のCode Unitで表現するのがUTF-16というエンコード方式です。しかし、16ビット(2バイト)で表現できる範囲は、65536種類(2の16乗)です。 現在、Unicodeに登録されているCode Pointは10万種類を超えているため、すべての文字とCode Unitを1対1の関係で表すことができません。

ポイント

  • JavaScriptでは「文字列はCode Unitが順番に並んだもの」として扱われます。
  • Code Pointを、Code Unitで表現するのがUTF-16というエンコード方式です。
  • Code Unitの上限が65536種類と決まっているが 現在、Unicodeに登録されているCode Pointは10万種類を超えています。
  • 1つのCode Unitでは表現しきれないものは2つのCode Unitで表現します。

サロゲートペア

UTF-16では2つCode Unitの組み合わせで1つの文字(1つのCode Point)を表現します。この仕組みをサロゲートペアと呼びます。

\uD800~\uDBFF:上位サロゲートの範囲 \uDC00~\uDFFF:下位サロゲートの範囲

ドラクエモンスターズに例えてみました。

サロゲートペアをドラクエモンスターズで言うと 普通に仲間にできるモンスター(Code Unit)は決まっていて、さらに新しいモンスター(Code Point)は増えているから、二体のモンスター を配合(サロゲートペア)する事で、新しいモンスター(Code Point)を表現している。

ようがんまじん + ひょうがまじん = ゴールデンゴーレム

そしてこの配合(サロゲートペア)されたゴールデンゴーレムにString#length プロパティは文字列におけるCode Unitの要素数を数えるため、ゴールデンゴールム.longthとすると結果は 2 となります。

  console.log("ゴールデンゴーレム".length); // => 2

参考

JS primer Code PointとCode Unitの違い