jQueryのコーディングスタイルをめぐる2つの哲学 ~汚染は悪か?そしてend()は便利か?

method chainを多用して記述を行うだけなんですが、「method chainが延々続くので書いてて楽しい」、「インデントをDOM構造と対応付けやすい」、「見かけ上変数、条件分岐、繰り返しが減るのでバグが発生しづらい」と言った利点があります。
(中略)

広域変数は$.extendで$に保持しましょう。

(中略)

function:すべてjQuery pluginとして実装しましょう。
2つ目の記事
jQuery使いが陥りやすい罠

method chainをつなげると中間変数も少なくなるしDOM構造との対応がついて書きやすいのですが、途中の状況を把握しづらくデバッグが難しくなるので適当なところで変数に受けましょう。

(中略)

jQueryに慣れるとwindow objectの使用をいかに避けるかを考えるようになり、jQueryと関係ないfunctionや変数まで$.hogehogeに実装しようとしてしまいます。
これはwindow objectの代わりにjQuery objectを汚染しているだけなので、素直にwindow objectを使用したほうが普通に実装しやすいでしょう。

(中略)

名前空間の汚染を気にするあまり何でも$.fnに納めてしまいがちですが、jQueryを使用しないのであれば普通にfunctionを定義しましょう。

どちらが正しいのか?

上記2つの記事は明らかに矛盾した内容なのですが、非常に面白い問題提起になっています。
これをどう解釈するか、プログラマの力量が問われていると思いました。

私の解釈


設計に懲りすぎるのもよくないし、設計について何も考えないのもよくない。
現場のニーズにあった妥協が必要である。


私は最初、1つ目の記事を読んで感銘を受けて、ふむふむと自分のJSコードを書き換えました。
  • end()とインデントを多用する
  • $.extendなどを駆使ししてグローバル変数を使わないようにする

延々と続くメソッドチェーン


$('.hoge').find('.tag')
        .find('h2')
            .text('TAG!')
            .end()
        .find('a')
            .addClass('tagLink')
            .each(function () {
                $(this).css('font-size', '1'+$(this).attr('title')+'0%');
            })
            .end()
        .end()
    end()
;
書いてるときは「これがjQuery流か、カッコイイ!」と興奮したのですが、 書き終わって自分のコードを眺め見ると「なんか読みにくいなー」

ブロック内のコードが数十行単位になると、いまどのスコープにいるのかわからなくなってしまいます。
結局下記のような一時変数を使うスタイルに落ち着きました。

var tags = $('.hoge').find('.tag')

tags.find('h2')
    .text('TAG!');

tags.find('a')
    .addClass('tagLink')
    .each(function () {
        $(this).css('font-size', '1'+$(this).attr('title')+'0%');
    });


メソッドチェーンが延々と続くよりは、一時変数をうまく使って式を終わらせた方が読みやすいと感じました。

グローバル変数 v.s. $.extend

こちらも、やはり広域変数を何個か使う程度なら、グローバル変数を使ってもよいのではないかという結論にたどりつきました。
$.extendなどを多用すると、コードを読む側が初心者の場合、学習コストが高くなると感じました。

一方、関数は$.fnを使ってプラグイン化するという発想は、モジュール化・コード再利用の観点から、積極的に利用したい思いました。

個人的な感想まとめ

  • グローバル変数は数個程度ならまあいいかな
  • end()使いすぎは読みにくい。一時変数を使った方がよい場合も。
  • $.fn.myfunc = function(){ ... } はわりと便利

(もちろんどちらがよいかは現場のニーズで決まるのであって、正解はないと思います。)
カテゴリ: