サロゲートペア:BMP外の文字
基本多言語面の外の文字がUTF-16でサロゲートペアを使用する方法と、JavaScriptの.lengthが1文字に対して2を返す理由を学びます。
Multi-byte Characters
詳細な説明
UTF-16のサロゲートペア
基本多言語面(BMP)にはUnicodeコードポイントU+0000からU+FFFFが含まれます。この範囲外の文字(補助面)は単一の16ビットコードユニットに収まらないため、UTF-16はサロゲートペア(2つの16ビットコードユニットの組み合わせ)としてエンコードします。
サロゲートペアの仕組み
U+1F600(😀 Grinning Face)の場合:
- 0x10000を引く:0x1F600 - 0x10000 = 0xF600
- 上位サロゲート:0xD800 + (0xF600 >> 10) = 0xD83D
- 下位サロゲート:0xDC00 + (0xF600 & 0x3FF) = 0xDE00
JavaScriptは2つのコードユニットとして保存:\uD83D\uDE00
JavaScript .lengthへの影響
"😀".length // 2 (サロゲートペア)
[..."😀"].length // 1 (コードポイント)
"😀".codePointAt(0) // 128512 (U+1F600)
サロゲートペアを使用する文字
| カテゴリ | 範囲 | 例 |
|---|---|---|
| 絵文字 | U+1F600–U+1FAFF | 😀 🚀 🍕 |
| 数学記号 | U+1D400–U+1D7FF | 𝐀 𝐁 𝐂 |
| 音楽記号 | U+1D100–U+1D1FF | 𝄞 |
| 歴史的文字 | U+10000–U+1007F | 𐀀 |
| CJK拡張B+ | U+20000–U+2A6FF | 珍しい漢字 |
壊れる文字列操作
一般的な文字列操作はサロゲートペアを破壊する可能性があります:
// 間違い:サロゲートペアを分割する可能性
str.substring(0, 1) // 上位サロゲートのみを返す可能性
str.charAt(0) // 上位サロゲートのみを返す
// 正しい:コードポイント対応のメソッドを使用
[...str].slice(0, 1).join("")
バイトサイズ
| エンコーディング | サロゲートペア文字あたりのバイト数 |
|---|---|
| UTF-8 | 4バイト |
| UTF-16 | 4バイト(2コードユニット × 2バイト) |
| UTF-32 | 4バイト(常に) |
興味深いことに、補助文字ではすべてのエンコーディングが同じ4バイトを使用します。違いはBMP文字でのみ重要です。
ユースケース
絵文字や珍しい文字を含む文字列を操作するJavaScriptアプリケーションを構築する際、サロゲートペアを理解することは、部分文字列操作、データベースストレージ、APIペイロード処理中のデータ破損を防ぐために不可欠です。