jQuery, getterとsetterのヘンテコ動作
Programming PHPと並行してjQueryのオンラインマニュアルを読んでいる。
今日とても変わっている実装だと思ったのはこちら。getterとsetterについての解説だ。
setterはセレクタで指定される全要素が対象となる。
$( "h1" ).html( "hello world" );
これはH1タグ全部を”hello world"に書き換える。
ところが、getterはセレクタで指定される先頭の要素の値だけしか返ってこない。
$( "h1" ).html();
これは先頭のH1タグの中身だけが返ってくる。setterのことを考えると全要素の中身が返ってきそうだが、全部ではない。1つだけ。
さらに、setterはjQueryオブジェクトを必ず返すが、getterはjQueryオブジェクトを返すとは限らない。
上の例なら、setterはメソッドチェーンを使ってさらにH1タグ全体に対して何か処理を加えることができるが、getterでは"hello world"などの文字列が返ってくるので追加の処理は行えない。
C言語からプログラミングを始めた身としては、まずgetterとsetterの書き方がまるでオーバーロード関数のようである、というのは直感的ではない。さらに、返ってくるオブジェクトが異なるというのも直感的ではない。
jQueryを使いこなしている人から見れば当たり前のことだろうが、見た目がほとんど同じなのに動作が全然違うというのは躓きやすそうなのでメモしておく。
これはなんでもありのJavaScriptだから許される仕様だ。ライブラリは何を返そうがどこでどんな変数の置き換えをしても許される。グローバル空間の汚染すら許される。そのため、ユーザーはライブラリについて一々マニュアルを読みまくる必要性が必ず生じる。仕様を知らなければ何もできない。しかも仕様は変わる。技術はすぐに移り変わる。1つ覚えたからといって未来永劫その知識を活用できる保証が全くない。大変な世の中になったものだ。
なお、メソッドチェーンならこんなこともできる。
$( "#content" )
.find( "h3" )
.eq( 2 )
.html( "new text for the third h3!" )
.end() // Restores the selection to all h3s in #content
.eq( 0 )
.html( "new text for the first h3!" );
ちょっと気持ち悪い。私ならend()は使わないで2行に分割して書くだろうな。