jQueryのメソッドチェーンでifを実現するiff plugin

紹介

タイトル通りのplugin
Ben Alman » jQuery iff: A chainable "if" statement

言及のきっかけとか

実用性がどうかとかより、以前似たようなものを実装しようとした者として、
そのシンプルな実装に感動したので言及しておく。
ちなみに私が作ったのはこの辺
条件付メソッドチェーンを実現するjQuery pluginを作ってみた - 文殊堂
if文の条件部に相当するメソッドに渡るのがtrueなら次のメソッドは実行するというのはさっくり実装出来たが、
条件付メソッドチェーン実現のためjQueryのラッパーを作ってみた - 文殊堂
複数メソッドをifの対象にするには結構七面倒くさいことをしないといけない。
と私は思っていた。


iff pluginでは、iffメソッドにfalsyな値を渡すか、
関数と引数のセットを渡してそれを実行したときにfalsyな値が返るかした時、
その次以降endメソッドが呼ばれるまで間DOM探索・操作系のメソッドが何もしなくなる。
iffメソッドとendメソッドでメソッドチェーンにif文のブロックのような構造が作れるのだ。
面倒くさいことをやっている上に既存のendメソッドの定義を上書きしているかと思ったらどちらも外れ。
やっていることはiffメソッドの追加のみ、実装は実質7行だった。

コードを読み解く

  $.fn.iff = function( test ) {
    var elems = !test || $.isFunction( test )
      && !test.apply( this, Array.prototype.slice.call(arguments, 1) )
      ? []
      : this;
    return this.pushStack( elems, 'iff', test );
  };

条件がtrueだった場合はthisをそのまま、
falseだった場合はから配列をthis.pushStackに渡している。
pushStackメソッドは本来どういうものかと言うと、
DOM探索系のメソッドで現在かかえているDOM要素をstackに積んで、
渡された探索結果をjQueryオブジェクト化して返すというもので、
find等による絞り込みの後endメソッドで絞り込み前の状態に戻る
等といったことができるのはpushStackメソッドのおかげ。


つまり、iff pluginの作者はこのpluginを、条件がtrueの場合は元と同じ、
条件がfalseの場合にはno hitとなるような
偽のDOM探索メソッドとして実装することで、
iffメソッドとendメソッドでメソッドチェーンにif文のブロックのような構造が作るのを実現した訳だ。
凄い発想だと思う。