【JavaScript】文字列の長さを取得する方法|length プロパティ・サロゲートペア対応・バイト数・配列の length まで解説

フォームの入力文字数チェック、テキストの省略表示、API のリクエスト制限など、文字列の長さを取得する操作はフロントエンド開発のあらゆる場面で必要になります。JavaScript では length プロパティで簡単に取得できますが、絵文字(サロゲートペア)を含む場合は想定と異なる値が返ることがあり注意が必要です。

この記事でわかること
・length プロパティの基本と戻り値
・length が返すのは「UTF-16 コードユニット数」
・サロゲートペア(絵文字)で length が想定と異なる理由と対策
・Intl.Segmenter で書記素クラスタ単位の正確なカウント
・バイト数(UTF-8)の取得方法
・配列の length との違い
・空文字判定・入力文字数制限・テキスト省略表示の実務パターン
スポンサーリンク

length プロパティの基本

構文
const len = str.length;
// 戻り値: 文字列の UTF-16 コードユニット数(0 以上の整数)
// 読み取り専用(代入しても変更されない)
基本例
console.log("Hello".length);     // 5
console.log("こんにちは".length); // 5
console.log("".length);           // 0(空文字)
console.log(" ".length);          // 1(半角スペース)
console.log("Hello World".length); // 11(スペースも1文字)

lengthプロパティです。メソッドではないため () を付けません。

NG: () を付けるとエラー
// "Hello".length()  // TypeError: "Hello".length is not a function
"Hello".length       // 5(正しい)
length はスペース、タブ、改行などの空白文字もすべて 1 文字としてカウントします。

length が返すのは「UTF-16 コードユニット数」

JavaScript の文字列は内部的に UTF-16 でエンコードされています。length が返す値は「見た目の文字数」ではなく、UTF-16 コードユニットの数です。

多くの文字(ASCII、ひらがな、カタカナ、漢字の大半)は 1 コードユニット = 1 文字なので問題ありませんが、一部の文字は 2 コードユニットを使います。

文字の種類 コードユニット数
ASCII(半角英数字) 1 "A".length → 1
ひらがな・カタカナ 1 "あ".length → 1
基本的な漢字 1 "漢".length → 1
絵文字(サロゲートペア) 2 "?".length → 2
一部の漢字(BMP外) 2 "?".length → 2

サロゲートペア(絵文字)で length が想定と異なる問題

絵文字や一部の漢字はサロゲートペア(2 つの UTF-16 コードユニットで 1 文字を表現)のため、length は見た目の文字数より大きい値を返します。

JavaScript
const text = "Hello?";

console.log(text.length);     // 7("Hello"=5 + ?=2)
console.log([...text].length); // 6(見た目の文字数)

スプレッド構文で見た目の文字数を取得する

スプレッド構文 [...str] は文字列を Unicode コードポイント単位で分割するため、サロゲートペアを 1 文字として扱います。

JavaScript
function visualLength(str) {
  return [...str].length;
}

console.log(visualLength("Hello?"));   // 6
console.log(visualLength("こんにちは?")); // 6
console.log(visualLength("?野家"));     // 3

結合絵文字(ZWJ シーケンス)の注意点

家族絵文字や国旗絵文字など、複数のコードポイントが結合した「結合絵文字」は、スプレッド構文でも正確にカウントできません。

JavaScript
const family = "?‍?‍?‍?"; // 家族絵文字(ZWJ シーケンス)

console.log(family.length);     // 11
console.log([...family].length); // 7(ZWJ と各絵文字がバラバラに)

このようなケースで正確にカウントするには Intl.Segmenter を使います。

Intl.Segmenter で書記素クラスタ単位のカウント

JavaScript
function graphemeLength(str) {
  const segmenter = new Intl.Segmenter("ja", { granularity: "grapheme" });
  return [...segmenter.segment(str)].length;
}

console.log(graphemeLength("Hello?"));    // 6
console.log(graphemeLength("?‍?‍?‍?"));       // 1(正確!)
console.log(graphemeLength("??"));         // 1(国旗も正確)
方法 絵文字 結合絵文字 ブラウザ対応
str.length × 2倍になる × 大幅に多い 全ブラウザ
[...str].length ○ 正確 × 分割される 全ブラウザ
Intl.Segmenter ○ 正確 ○ 正確 Chrome 87+ / Safari 15.4+(IE/Firefox 非対応)
Intl.Segmenter は 2026 年現在 Firefox では未対応です。Firefox 対応が必要な場合はポリフィルを使うか、[...str].length で妥協する方法があります。

文字列のバイト数を取得する方法

length は「文字数」であり「バイト数」ではありません。UTF-8 でのバイト数が必要な場合は TextEncoder を使います。

JavaScript
function byteLength(str) {
  return new TextEncoder().encode(str).length;
}

console.log(byteLength("ABC"));     // 3(ASCII: 1バイト×3)
console.log(byteLength("あいう"));  // 9(日本語: 3バイト×3)
console.log(byteLength("?"));      // 4(絵文字: 4バイト)
文字 length(文字数) UTF-8 バイト数
"A" 1 1
"あ" 1 3
"?" 2 4
API のリクエストサイズ制限やデータベースのカラム幅チェックでは、文字数ではなくバイト数で判定する必要があります。詳しくは「文字列のバイト数を取得する方法」を参照してください。

配列の length との違い

文字列の length は読み取り専用ですが、配列の length読み書きの両方が可能です。

比較項目 文字列の length 配列の length
戻り値 UTF-16 コードユニット数 要素数
書き込み 不可(代入しても無視される) 可能(要素数を増減できる)
JavaScript
// 文字列: 読み取り専用
const str = "Hello";
console.log(str.length); // 5
// str.length = 3;       // 無視される(strict mode ではエラー)

// 配列: 書き込み可能
const arr = [1, 2, 3, 4, 5];
arr.length = 3;
console.log(arr); // [1, 2, 3](末尾が切り捨てられる)

実務でよく使うパターン

空文字列の判定

JavaScript
function isEmpty(str) {
  return !str || str.length === 0;
}

console.log(isEmpty(""));        // true
console.log(isEmpty(null));      // true
console.log(isEmpty(undefined)); // true
console.log(isEmpty("Hello"));   // false

// 空白のみも空とみなす場合
function isBlank(str) {
  return !str?.trim();
}
console.log(isBlank("   ")); // true

入力文字数のリアルタイムカウンター

HTML
<textarea id="message" maxlength="200" placeholder="メッセージを入力"></textarea>
<p><span id="charCount">0</span> / 200</p>
JavaScript
const textarea = document.getElementById("message");
const counter = document.getElementById("charCount");

textarea.addEventListener("input", () => {
  counter.textContent = textarea.value.length;
});

テキストの省略表示(truncate)

JavaScript
function truncate(str, maxLength) {
  if (str.length <= maxLength) return str;
  return str.slice(0, maxLength) + "...";
}

console.log(truncate("JavaScriptで文字列の長さを取得する方法", 15));
// "JavaScriptで文字列の..."

パスワードの長さバリデーション

JavaScript
function validatePassword(password) {
  const errors = [];

  if (password.length < 8) {
    errors.push("8文字以上で入力してください");
  }
  if (password.length > 64) {
    errors.push("64文字以下で入力してください");
  }

  return errors.length === 0
    ? { valid: true }
    : { valid: false, errors };
}

console.log(validatePassword("abc"));
// { valid: false, errors: ["8文字以上で入力してください"] }

関連記事

よくある質問

Q絵文字を含む文字列で length が想定より大きいのはなぜですか?
AJavaScript の length は UTF-16 コードユニット数を返します。絵文字はサロゲートペア(2 コードユニット)のため、見た目 1 文字でも length は 2 になります。見た目の文字数を取得するには [...str].length を使ってください。
Qnull や undefined に .length を使うとエラーになります。
Anull.lengthundefined.lengthTypeError になります。事前に if (!str) でチェックするか、オプショナルチェーニング str?.length ?? 0 を使うと安全です。
Qlength はメソッドですか?プロパティですか?
Aプロパティです。str.length のように () なしでアクセスします。str.length() と書くと TypeError になります。
Q改行やタブも length にカウントされますか?
Aはい、\n(改行)は 1、\t(タブ)は 1、\r\n(Windows 改行)は 2 としてカウントされます。
Q文字数ではなくバイト数で制限したい場合はどうすればよいですか?
Anew TextEncoder().encode(str).length で UTF-8 バイト数を取得できます。API のサイズ制限やデータベースのカラム幅チェックではバイト数での判定が必要です。

まとめ

JavaScript で文字列の長さを取得するには length プロパティを使います。

  • 基本: str.length で UTF-16 コードユニット数を返す
  • サロゲートペア: 絵文字は length が 2 になる → [...str].length で対策
  • 結合絵文字: ZWJ シーケンスは Intl.Segmenter で正確にカウント
  • バイト数: new TextEncoder().encode(str).length で UTF-8 バイト数
  • 配列との違い: 文字列の length は読み取り専用、配列は書き込み可能

入力バリデーションやテキスト省略など日常的に使うプロパティですが、絵文字を含むケースではカウント方法の選択が重要です。要件に応じて使い分けてください。