jQueryのval()は内部で何をしているのか

val()は「valueを取る関数」ではありません

jQueryでフォーム値を取得するとき、多くの人が最初に覚えるのがval()です。

$('#name').val();

一見すると「inputのvalueを取得しているだけ」に見えます。しかし実際には、val()は単なるショートカットではありません。結論から言うと、val()はフォーム要素ごとの違いを吸収するための統一インターフェースです。

input、textarea、select、checkbox、radioは、それぞれvalueの扱いが違います。jQueryのval()はそれを内部で判定し、同じ書き方で扱えるようにしています。

ネイティブのvalueは統一されていない

JavaScriptのDOMでもvalueは取得できます。

document.getElementById('name').value;

ただしこれはinputに限った話です。selectになると話が変わります。

document.getElementById('pref').value;

動きますが、実際に使われているのはselectedIndexとoptionのvalueの組み合わせです。ブラウザによっては挙動が異なっていました。

checkboxやradioはさらにややこしくなります。

  • チェックされていないとvalueは意味を持たない
  • 複数選択では配列になる
  • radioはグループで判定する

つまり「フォーム値取得」は単純なプロパティ参照ではありませんでした。

val()が内部で行っている処理

jQueryのval()は要素の種類を判定します。

  • input[type=text] → valueプロパティ
  • textarea → valueプロパティ
  • select → 選択optionのvalue
  • checkbox → checked状態と組み合わせ
  • radio → 同一nameの選択要素を検索

特にradioは象徴的です。

<input type="radio" name="gender" value="m">
<input type="radio" name="gender" value="f">

ネイティブではこう書きます。

document.querySelector('input[name=gender]:checked').value;

しかしjQueryは単に次です。

$('input[name=gender]:checked').val();

ここでやっているのはvalueの取得ではなく、選択状態の解釈です。

値を設定するときの挙動

取得だけでなく設定も重要です。

$('#name').val('Taro');

これはvalueプロパティを変更しています。しかしselectでは違います。

$('#pref').val('tokyo');

jQueryは内部でoptionを探し、selected状態を変更します。さらにcheckboxの配列指定も可能です。

$('input[name=hobby]').val(['music','movie']);

これは一致するvalueを持つcheckboxをチェック状態にします。単なるvalue代入ではありません。

なぜこれが必要だったのか

昔のブラウザでは、フォーム要素の扱いが統一されていませんでした。

  • selectのvalueが取得できないブラウザ
  • radioのchecked判定が不安定
  • textareaの改行コード差異

jQueryはこれを吸収しました。つまりval()は便利メソッドではなく、ブラウザ差異の正規化レイヤーです。

よくある誤解

val()はテキスト入力専用と思われがちですが、実際はフォーム要素全体のAPIです。checkboxやselectでこそ意味があります。

逆に次の使い方は誤解を招きます。

$('#form').val();

form自体にはvalueがありません。jQueryはundefinedを返します。val()はフォーム全体の値をまとめて取得する関数ではありません。

注意点:changeイベントとの関係

val()で値を設定してもchangeイベントは発火しません。

$('#name').val('Taro');

これはユーザー操作ではないためです。必要なら明示的に発火します。

$('#name').val('Taro').trigger('change');

ここを理解していないと、入力監視ロジックが動かない原因になります。

val()とattrの違い

よくある間違いがこれです。

$('#name').attr('value','Taro');

これは初期値を書き換えますが、現在の入力値は変わりません。val()はプロパティ、attrは属性です。チェックボックスのcheckedと同じ構造です。

結局val()は何をしているのか

val()はvalue取得関数ではありません。

  • 要素の種類判定
  • 状態の解釈
  • プロパティ操作
  • ブラウザ差異吸収

これらをまとめたAPIです。フォーム操作がjQueryで簡単だった理由の一つがここにあります。

見た目は一行ですが、内部ではかなり多くの条件分岐が動いています。val()はフォーム入力という「人間の操作」を、JavaScriptから安全に扱うための窓口だったと言えます。