FunctionChain

JavaScriptのすてきなのは、関数を返値として設定できること、関数もまたプロパティーを持っていること。
で、こんな関数のようなクラスのようなものを作ってみました。これをつかうと

document.onload = FunctionChain( function(e){
  alert('読み込まれました');
} );
document.onload.append( function(e){
  alert('ました(2回目)');
} );

みたいなことができます。
…ええ、DOMイベントに使う場合は addEventListener を使えばいいんですが。この関数は、そんな機構が用意されていない場合でも気にせず使えます、ということで。

なかみ

FunctionChain=function(){
  if( this.constructor == FunctionChain ){
    this.list = new Array;
    return this;
  }
  var r = new FunctionChain;
  var f = function(){ return r.run( arguments,this ); };
  r._attach( f );
  for(var i=0;i<arguments.length;i++) f.append( arguments[i] );
  return f;
}
FunctionChain.prototype.constructor = FunctionChain;
FunctionChain.prototype.attach = function(f){
  var self= this;
  f.unshift = function(l){ return self.unshift(l); };
  f.append = function(l){ return self.append(l); };
  f.remove = function(l){ return self.remove(l); };
  f.FunctionChain = self; // 一応外部にも公開
}
FunctionChain.prototype.run = function(args,thisObject){
  for( var i=0; i<this.list.length; i++ ){
    if( this.isEnd( this.list[i].apply( thisObject,  args[i] ), args ) )return false;
  }
  return true;
}
/**
  関数チェインの終了条件。関数がfalseを返した場合に処理を終了する。
  ここを書き換えれば、「終了しない」「イベントのreturnValueがfalseの時だけ終了する」などに変更できます。
 */
FunctionChain.prototype.isEnd = function( result, calledarg ){
  if( result === false )return true;
}
FunctionChain.prototype.remove = function(func){
  for( var i=0; i<this.list.length; i++ )
    if( this.list[i] == func ) return this.list.splice(i,1);
}
FunctionChain.prototype.append = function( func ){
  if( this.keepUnique ) this.remove( func );
  this.list.push( func );
}
FunctionChain.prototype.unshift = function( func ){
  if( this.keepUnique ) this.remove( func );
  this.list.unshift( func );
}
FunctionChain.prototype.keepUnique = true;

*1

ちょっと修正

FunctionChain中の関数でthisがFunctionChain自信になるのを修正

*1:ライセンスはLGPLで。