目次
概要
JavaScriptで文字列の長さを取得するには、通常 length プロパティを使用します。
ただし、絵文字や一部の漢字(サロゲートペア)は、length プロパティでは「2文字」としてカウントされてしまう仕様があります。
本記事では、基本的な長さの取得方法と、絵文字を正しく1文字としてカウントするための Array.from() を使ったテクニック、そしてリアルタイム文字数カウンターの実装例を解説します。
仕様(入出力)
- 入力: 任意の文字列(日本語、英語、絵文字を含む)
- 出力:
.lengthによる単純なバイト数的なカウントArray.from()による見た目通りの文字数カウント- テキストエリア入力時のリアルタイムカウント表示
基本の使い方
通常は .length を使いますが、厳密なカウントが必要な場合は配列に変換してから長さを測ります。
カウント方法の比較
| 対象の文字列 | コード | 結果 | 備考 |
"JavaScript" | "JavaScript".length | 10 | 半角英数字は問題なし |
"ウェブ" | "ウェブ".length | 3 | 一般的な日本語も問題なし |
"🍎" (絵文字) | "🍎".length | 2 | 内部表現が2文字分のため |
"🍎" (絵文字) | Array.from("🍎").length | 1 | 配列化して正しくカウント |
コード全文(HTML / JavaScript)
HTML (index.html)
テキストエリアと、文字数を表示する span 要素を用意します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Character Counter</title>
<style>
.container { font-family: sans-serif; padding: 20px; }
.textarea {
width: 100%;
height: 100px;
padding: 10px;
font-size: 16px;
}
.counter { margin-top: 10px; font-weight: bold; }
</style>
<script src="char-count.js" defer></script>
</head>
<body>
<div class="container">
<h1>文字数カウンター</h1>
<textarea class="textarea" placeholder="ここに入力してください"></textarea>
<p class="counter">現在の文字数: <span class="string_num">0</span> 文字</p>
</div>
</body>
</html>
JavaScript (char-count.js)
ユーザーの入力コードにあった誤字(dcument, fuction 等)を修正し、サロゲートペア(絵文字)に対応したロジックを実装しました。
/**
* 文字列の長さを正しく取得する関数
* 絵文字なども見た目通り「1文字」としてカウントします
*/
const getTrueLength = (str) => {
// Array.from() で文字列を1文字ずつの配列に分解してから length を取得
return Array.from(str).length;
};
// DOM要素の取得
const textarea = document.querySelector(".textarea");
const stringNum = document.querySelector(".string_num");
/**
* キーアップイベントハンドラ
*/
function onKeyUp() {
const inputText = textarea.value;
// 基本的なカウント(絵文字は2文字扱い)
// stringNum.innerText = inputText.length;
// 絵文字対応のカウント(推奨)
stringNum.innerText = getTrueLength(inputText);
console.log(`生のlength: ${inputText.length}`);
console.log(`Array.from: ${Array.from(inputText).length}`);
}
// イベントリスナーの設定
// 'keyup' だけだと貼り付け操作などで反応しない場合があるため 'input' 推奨ですが
// ここでは元のコードに合わせて keyup を使用します
if (textarea) {
textarea.addEventListener("keyup", onKeyUp);
}
カスタムポイント
inputイベントの利用:実務ではkeyupではなくtextarea.addEventListener("input", ...)を使用することを推奨します。inputイベントなら、マウスの右クリック貼り付けやドラッグ&ドロップによる入力も検知できるためです。- スプレッド構文:
Array.from(str).lengthは[...str].lengthと書くことも可能です。どちらも結果は同じです。
注意点
- サロゲートペア:JavaScriptの内部文字コード(UTF-16)では、多くの絵文字や一部の漢字(𠮷など)を2つのコード(サロゲートペア)で表現します。
.lengthはこれを「2」と数えてしまうため、Twitterのような「文字数制限」を作る際はArray.from()での正確なカウントが必須です。 - 結合文字:「か」+「濁点」で「が」を表現するような結合文字の場合、
Array.fromでも「2文字」とカウントされることがあります。これを厳密に1文字とするには、Intl.Segmenterという新しいAPIが必要です。
まとめ
- 単純な長さチェックなら
文字列.length。 - 絵文字を含む「見た目の文字数」を数えたいなら
Array.from(文字列).length。 - 入力フォームの監視には
keyupイベントまたはinputイベントを使用する。
