LoginSignup
3
2

More than 1 year has passed since last update.

【JavaScript】文字列とUnicode

Posted at

概要

JavaScriptを学習、理解を深めるため「JavaScript Primer 迷わないための入門書」を読み、
理解した内容等を記載していく。

【JavaScript】JavaScript入門一覧」に他の記事をまとめています。

この記事で理解できること

  • JavaScriptにおける、Unicodeの構成要素との関係

Code Point

  • Unicodeはすべての文字に一意のIDが定義されており、そのIDをCode Point(符号位置)と呼ぶ。
  • Code Pointを扱うメソッドとしてcodePointAtメソッド、String.fromCodePointメソッドが存在する。
  • それぞれES2015から導入された。

codePointAtメソッド

  • 文字列の指定インデックスにある文字のCode Pointの値を返す。
// 引数にインデックスを指定し、"あ"のCode Pointを取得
console.log("あいうえお".codePointAt(0)); // => 12354

String.fromCodePointメソッド

  • 指定したCode Pointに対応する文字を返す。
  • Code Pointを16進数に変換後、Unicodeエスケープシーケンスで指定しても同じように文字を返す。
// "あ"のCode Point(12354)を指定
console.log(String.fromCodePoint(12354)); // => あ

// "あ"のCode Point(12354)を16進数に変換
const hex = "あいうえお".codePointAt(0).toString(16);
console.log(hex); // => 3042

console.log("\u{3042}"); // => あ

Code PointとCode Unitの違い

  • Code Point(符号位置)は、その文字のID
    • 文章にすると..「この文字のIDはXXXです」
  • Code Unit(符号単位)は、文字列の構成要素の最小単位
    • 文章にすると..「JavaScriptの内部的に、この文字列はCode Unit2つで構成されている」
    • JavaScriptが内部的に採用しているUTF-16では1Code Unitでは65536種類しか表現できない。
    • 65537種類目以降を表現する場合、サロゲートペアという仕組みを用いて文字列を表現する。

サロゲートペア

  • 2つのCode Unitを組み合わせて(合計4バイト)1文字を表現する仕組み。
  • UTF-16では\uD800~\uDBFF(上位サロゲート)\uDC00~\uDFFF(下位サロゲート)として範囲を設けている。
  • 上位サロゲート下位サロゲートがペアとなる。
// 1文字なのにlengthが2(Code Unitが2つで表現されているため)
console.log("𩸽".length) // => 2

// Code Unitを出力
for (let i = 0; i < "𩸽".length; i++) {
  console.log("𩸽".charCodeAt(i).toString(16));
}
// => d867(上位サロゲート)
// => de3d(下位サロゲート)

console.log(`\ud867\ude3d`); // => 𩸽

正規表現の.とUnicode

  • ES2015から正規表現にu(Unicode)フラグが追加された。
  • uフラグありの場合、文字列をCode Pointが順番に並んだものとして扱う。
  • uフラグなしの場合、文字列をCode Unitが順番に並んだものとして扱う。
const str = "𩸽は白米に合う";

// キャプチャで𩸽を取得し検証
const pattern1 = /(.)は白米に合う/;
const pattern2 = /(.)は白米に合う/u;

console.log(str.match(pattern1)); // => [ '\ude3dは白米に合う', '\ude3d', index: 1, input: '𩸽は白米に合う', groups: undefined ]
console.log(str.match(pattern2)); // => [ '𩸽は白米に合う', '𩸽', index: 0, input: '𩸽は白米に合う', groups: undefined ]

// uフラグなしの場合は、下位サロゲートのみが取得され、正しく表示されていない
// uフラグありの場合は、Code Pointとして扱うため"𩸽"が取得できている

Code Pointの数を数える

  • JavaScriptには、文字列におけるCode Pointの個数を数えるメソッドは存在しない。
  • 文字列をCode Pointごとに区切った配列へ変換して、配列の長さを数えるのが簡潔とされている。

Array.fromメソッド

  • 引数にiterableなオブジェクトを受け取り、それを元にした新しい配列を返す。
  • 文字列もiterableオブジェクトであるため、Array.fromメソッドによって1文字ごとに区切った配列へと変換できる。

iterableなオブジェクトとは
Symbol.iteratorという特別な名前のメソッドを実装したオブジェクトの総称。
for...of文などで反復処理が可能なオブジェクト。

// 以下の文字列の長さは7ではなく8
const str = "𩸽は白米に合う";
console.log(str.length); // => 8

// 配列を作成
const strings = Array.from(str);

console.log(strings);         // => [ '𩸽', 'は', '白', '米', 'に', '合', 'う' ]
console.log(strings.length);  // => 7(1文字ごとに区切った配列の長さ = 実際に人間が目で見た文字の数となっている)
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2