Valibotのメンテナーである筆者が、JavaScriptで文字列の長さを数える難しさと、Valibotが提供する3種類の文字数カウント方法を解説しています。JavaScriptのString.lengthはUTF-16コード単位(文字をエンコードする際の16ビット単位。基本的な文字は1単位で表されるが、絵文字などの一部の文字は2単位のペア=サロゲートペアで表される)の数を返すため、'😀'.lengthは2になるなど、直感とずれることがあります。

maxLengthはdataset.value.lengthを直接使いUTF-16コード単位を数え、maxCodePointsはサロゲートペアを見つけるたびに1個ずつ引いていく独自関数でコードポイント数を数えます。一方、maxGraphemesはIntl.Segmenter(Web標準の文字分割API)を使い、👨‍👩‍👧‍👦のような合成絵文字も1文字として数えられます。

著者は「自己紹介を160文字で」のような文字数制限を設けたい場合はmaxGraphemesを使うべきだと述べています。三者ともWeb標準APIに則った実装とのことです。

出典が伝えている要点

  • 著者(ysknsid25)はValibotのメンテナーである
  • Valibotは検証ライブラリであり、文字列長を複数の単位でカウントする機能を提供している
  • JavaScriptのString.lengthはUTF-16コード単位の数を返す
  • '😀'.lengthは2を返す(サロゲートペアのため)
  • Valibotのmax​Lengthはdataset.value.lengthを直接使用し、UTF-16コード単位を数える
  • Valibotのmax​CodePointsは_getCodePointCount()という関数で実装されている
  • _getCodePointCount()はサロゲートペアを1つ見つけるたびに1個ずつ引いていく方法でコードポイント数を数える
  • _getCodePointCount()はcodePointAt(i) <= 0xffffで基本多言語面か追加面かを判定している
  • Valibotのmax​GraphemesはIntl.Segmenterを使用してグラフェムクラスタ単位で文字列を分割している
  • Intl.Segmenterを使うと👨‍👩‍👧‍👦のような合成絵文字を1文字として数えられる
  • maxLength・maxCodePoints・maxGraphemesのすべての実装はWeb標準APIに則っている
  • 著者は『自己紹介を160文字で』のような文字数制限を設けたい場合はmaxGraphemesを使うべきだと述べている

原文より

自己紹介を160文字で

出典: blog.inorinrinrin.com

← 2026.09.19 の号を通しで読む