日常的に使う漢字のほとんどは基本多言語面(BMP)に収まっており、1文字が1つの\uXXXXコードになる。しかし人名や地名に使われる一部の異体字は補助漢字面(U+20000以降)にあり、JavaScriptの内部表現であるUTF-16ではサロゲートペア――2つのエスケープコードの組み合わせ――として表現される。
「見た目は1文字」なのにコードは2つという罠
ある人名用漢字が補助漢字面にある場合、その1文字は画面上では他の漢字と何も変わらず表示されるが、内部的には\ud840\udd9fのような2つのコード単位に分かれている。文字列を1文字ずつ処理するプログラムがこの違いを考慮していないと、正しく表示されていた漢字が突然文字化けする原因になる。
JSONとエスケープシーケンス
JSON仕様では、文字列中の任意の文字を\uXXXXとしてエスケープできる。これはデータがプログラムで生成され、互換性のためにシリアライザが意図的にASCII以外の文字を避ける場合によく見られ、「東京」のような単語もJSON上では複数のエスケープコードの並びとして表示されることがあります。
必要になる場面
- APIのJSONレスポンスでエスケープシーケンスの裏に隠れたテキストを、わかりやすい言葉で読む。
- ASCII以外の文字を受け付けない環境向けに文字列を準備する。
- 外部データを扱う際のエンコードの問題を診断する。
よくある間違い: サロゲートペアの分断
文字列を途中で切り詰めたり、サロゲートペアを考慮せずにエスケープコードを1つずつ処理したりすると、ペアの前半と後半が分離されることがある。これは絵文字だけでなく、補助漢字面にある稀な漢字にも同じように起こりうる問題で、結果は不正な「孤立した」コード単位になる。