初心者向けにやさしく、例をたくさん使って length の仕組みと注意点&実務で使える代替方法 を説明します。図や難しい理屈は最小限にして「見てわかる」例で進めます。
1. まずは基本:.length で何が取れるの?
- JavaScript の
文字列.lengthは その文字列を内部で表している「UTF-16 のコードユニット(16ビット単位)」の個数 を返します。普通の英数字や日本語(多くの場合)は 1 つのコードユニット=lengthが 1 になるので「文字数」として期待どおりに見えます。
例:
let a = "Hello";
console.log(a.length); // 5
let b = "東京都";
console.log(b.length); // 3
JavaScript(上の例は .length が普通に「文字数」を返すケース)
2. 注意!見た目は 1 文字でも .length が 2 になる場合
- 絵文字など一部の文字(Unicode の「BMP(基本多言語面)」外のコードポイント)は UTF-16 では 2 つのコードユニット で表現されます。これを サロゲートペア(surrogate pair) と呼びます。そういう文字を含むと
.lengthが 2 を返してしまい、見た目の「文字数」とズレます。
例(絵文字):
let emoji = "😊";
console.log(emoji.length); // => 2 ← 見た目は 1 だけど length は 2
JavaScript別の例(複合的):
console.log("👨👩👧👦".length); // 複雑なファミリー絵文字はさらに長くなることがある
JavaScript3. 「見た目の文字(ユーザーが期待する 1 文字)」の数を数える方法
用途に応じて 3つの実用的な方法を紹介します。どれを使うかは「どのレベルで正確に数えたいか」によります(単純な絵文字対策か、さらに合字/結合文字(e + ´ など)まで正しく扱うか)。
方法 A — スピード重視で簡単:スプレッド構文([...str])または Array.from
これらはUnicode のコードポイント単位で分割してくれるので、サロゲートペア(多くの絵文字)を 1 と数えられます。古いブラウザ以外ではよく使われます。
let s1 = "Hello😊"; // 見た目 6 文字(最後は絵文字)
console.log(s1.length); // 7 (UTF-16 コードユニットの数)
console.log(Array.from(s1).length); // 6 ← 期待どおり
console.log([...s1].length); // 6 ← 同じ
JavaScript方法 B — イテレーション(確実): for...of で走査してカウント
for...of は文字列をコードポイント単位で繰り返すので、絵文字を 1 と数えられます。
let s2 = "a😊b";
let count = 0;
for (const ch of s2) { count++; }
console.log(count); // 3
JavaScript方法 C — 場合によっては最も正確:Intl.Segmenter(グラフーム単位)
ユーザーに見える「1 文字(グラフーム)」単位で分割する API。地域差(言語)に依存する分割も扱え、合字や結合マーク(e + ́ など)もまとめて 1 文字扱いにできます。より正確に「ユーザーが見る文字数」を数えたいときに使います(ただし古い環境では未対応のことがあるのでポリフィル確認を)。
// グラフーム(見た目の1文字)で数える例
const seg = new Intl.Segmenter(undefined, { granularity: "grapheme" });
const segments = Array.from(seg.segment("e\u0301😊")); // "e"+"́" と 絵文字
console.log(segments.length); // 2 ("é" と 絵文字)
JavaScript4. どれを使えばいい?実務的な選び方
- 単純に「ほとんど英数字・日本語で、絵文字が来ない前提」→
.lengthで OK。 - ユーザー入力に絵文字が入る可能性がある(チャット、コメント欄、名前など)→
Array.from(str).lengthや[...str].length、またはfor...ofを使う。 - 「見た目の文字(グラフーム)」での厳密なカウントが必要(文字数制限や正確な UI 表示など)→
Intl.Segmenterを検討(対応ブラウザ/環境を要確認)。
まとめ
string.lengthは UTF-16 のコードユニットの数 を返す。通常の文字は問題ないが、絵文字など一部は 2 になる。- 絵文字や特殊文字を正しく 1 文字として数えたいときは、
Array.from/[...str]/for...ofを使う。もっと厳密に「見た目の文字」を数えるならIntl.Segmenter。

