【JavaScript】文字列の詳細【中級者】

  • このエントリーをはてなブックマークに追加

JavaScriptの「文字列」について、掘り下げて学んでみる。

–名著JavaScript:the good parts 「良いパーツ」によるベストプラクティス [ ダグラス・クロフォード ] P11 ここから–
JavaScriptは、ユニコードが16ビットの文字集合だったときに設計されているため、JavaScriptのすべての文字は16ビット長さになっている。
JavaScriptは単一の文字を保持するために文字型の変数を使うことはできない。1文字の文字を扱うには、1文字だけを含んだ文字列を作ることになる。
–名著JavaScript:the good parts 「良いパーツ」によるベストプラクティス [ ダグラス・クロフォード ] P11 ここまで–



JavaScriptは元々16ビットの文字コードを採用していた。しかし、ユニコードが16ビットの文字集合では収まりきらない多くの文字をサポートするために拡張された。現在のJavaScriptエンジンでは、16ビットだけでなく、32ビットの文字もサポートしている。
JavaScriptはUTF-16エンコーディングを使用して文字を表現するため、最高で32ビット(4バイト)の文字も扱うことができます。通常、大部分の文字は16ビット(2バイト)で表現されますが、一部の文字(サロゲートペアを持つ文字など)は32ビットで表現されます。

サロゲートペアは、Unicode の符号位置がU+D800からU+DBFFまでの先行サロゲート (High Surrogate)とU+DC00からU+DFFFまでの後続サロゲート(Low Surrogate)から成る特別な文字ペアである。これらのサロゲートペアは、通常の16 ビットのUnicode符号位置では表現できないサロゲートペアの文字を表現するために使用される。

サロゲートペアの例
魚の「ホッケ」
よし野家の「よし」
※wordpressでは「ホッケ」と「よし」が表示できないことが判明。

次のコードで文字列のバイト数を求める。
サロゲートペア以外とサロゲートペアでカウントが違う。
サロゲートペア以外とサロゲートペアを判定することはできる。
charCodeAtメソッドでUnidodeコードポイントを取得して、サロゲートペアであるかを判定する。

残念ながら、JavaScriptでは、直接的に1文字が16ビットであると判定することはできない仕様になっている。サロゲートペアが32ビットで1文字、サロゲートペア以外が16ビットで1文字である確認はできないようだ。もやもやするけど、この記事でのJavaScriptの文字列の掘り下げはここまでとする。


function getBitLength(str) {
  let bitLength = 0;
  for (let i = 0; i < str.length; i++) {
    const codePoint = str.charCodeAt(i);
    console.log('codePoint = ' + codePoint);

    if (codePoint >= 0xD800 && codePoint <= 0xDBFF) {
      // サロゲート ペアの先行サロゲート
      const nextCodePoint = str.charCodeAt(i + 1);
      if (nextCodePoint >= 0xDC00 && nextCodePoint <= 0xDFFF) {
        // サロゲート ペアの後続サロゲート
        bitLength += 32; // サロゲート ペアは 32 ビット
        i+=1; // 次の文字も処理
      } else {
        // 無効なサロゲート ペアの場合、通常の文字として扱う
        bitLength += 16;
      }
    } else {
      // 通常の文字
      bitLength += 16;
    }

  }
  return bitLength;
}

const myString = "a";
const bitLength = getBitLength(myString);
console.log(`文字列のビット数: ${bitLength}`); // 16

const myString2 = "1";
const bitLength2 = getBitLength(myString2);
console.log(`文字列のビット数: ${bitLength2}`); // 16

/*

codePoint = 97
文字列のビット数: 16
codePoint = 49
文字列のビット数: 16

*/
  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*