愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

jQueryオブジェクトを入れる変数の名前を$で始める話

前提として、何度も同じelementを操作するのに毎回 $("#your complicated.selector").css({"...":"..."}); とか書いてる奴はくたばれ。それは、参照するデータが同じなのに毎回DBに問い合わせてるのと同じだぞ。

$で変数名を始めるのはなんでキモいか

僕がjQueryを使うときは$()関数で返ってきたオブジェクトを入れる変数名を$から始める、ということをけっこうよくやるのだけども、それについて「なんかキモくないですか」という意見があったのでちょっと考えてみる。ちなみにそれをやり始めたのはどこかで見たからだと思うんだけど、ソースは忘れた。

jQuery objectをつっこむ変数の名前を$で始めることが気持ち悪い理由はだいたい以下の2つくらいだと思う

  • オブジェクトの型(のようなもの)に基づいてprefixをつけているところに、ハンガリアン的な闇のオーラを感じる
  • $が識別子に使えるのはまあいいとして、それはjQueryとかprototypeとかのような特例のみに止めておくべきだ

どっちもそれなりに頷ける理由ではあるし、これらの理由を除いてもなんか生理的にアレだなあ、という人はいると思う。
実際、僕も "JavaScriptでjQueryを使うとき" 以外のプログラミングでは、こういう命名はまず行わない。

なんかめんどくさいアレ

じゃあなんでそんな特例をJS + jQueryの場合だけ自分に認めてるかっていうと、jQueryを使っていると何だかんだでjQueryオブジェクトと生DOM Objectを区別する必要があるからである。CSSセレクタを食わせた場合の$()関数はjQuery.fnをprototypeとしたArrayっぽいものを返すので、それをむきむきして生のElementを触りたい場合は

    $("#id")[0];
    $("#id").get(0);

とかしなくてはいけない。生DOM触る必要のあるやつだけgetElement(s)ByHogehogeとかで取ればいいんじゃね?と思う人もいるかもしれんが、コード書いてるとどうしても相互に行き来する必要が出てくる。

生DOM Elementを逆にjQuery objectでくるむ必要が出てくる場合もけっこうあって

    $(this).hogehoge();

    $(".class-a").each(function(i, elem) {
        $(elem).html("hogehoge");

        // or

        $(this).html("hogehoge");
    });

みたいなことをやっているコードにお目にかかった or 自分でそれを書いたことがある人はけっこうな数になるのではないだろうか。
jQuery objectをほぐしたりくるんだりするために [0] とか $(this) とか書いたりしている間にも人生の時間は過ぎ去り、心のマナは減り、ウガンダの子供達の命は失われているのだ。僕らは一体何をやっているんだ!

(※「最近のjQueryではその辺のことをうまく解決する方法があるよ!」っていう人は教えて頂けるとありがたいです)

割とどうしようもない

こういう沙汰になってしまうのはなにもjQueryが悪いわけじゃなくて、ライブラリを設計するときに「よし、もろもろの便利関数を生やしたArray的な何かで生のElementをくるんで返しちゃおう!」と決めた時点で逃れられない運命としてついてきた呪いなんである。
こういった設計というのは、一定の利便性を手に入れる代わりに一定の不便さを引き受けるシーソーゲームなんである。多分。

おそらく今のところ、JSでDOMを操作するラッパーライブラリの設計には「くるんで返すか、くるまずに返すか」という2択しかなくて、スマートな3択目が今のところ僕の貧弱な頭脳では思いつかない。ES5のfeatureを駆使していい環境だったとしてもやっぱり思いつかない。


ちょっと脱線したけど、jQueryを使っているとどうしても jQuery object <-> 生のElement 間の行き来を明示的に行う必要が出てきて、それらの操作がゴチャゴチャ書いてあるコードは読む人にコンテキストスイッチの負荷を強いるのである。実際の中身は似たようなものなのに違う動きをするものなので余計に厄介。なので、多少なりとも自分 / 他人による解読を助けるためにjQuery objectを入れる変数の名前には (そのデメリットも考慮した上で) $つけてもいいんじゃね?というのが僕の立場。


jQueryクックブック

jQueryクックブック