2012年6月10日日曜日

javascriptとfunction型 その3

function型が第一級型ということは、functionを戻り値にすることもできます。
が、これの使い方は正直言ってややレベル高いです。。。
詳しく知りたい方は、「カリー化」「部分適用」「クロージャ」あたりの単語でgoogle先生に訊いてみると幸せになれるかも。

今回は、ブログのタイトルもタイトルなので、ちょっとメタルを絡めたコードを例を書いてみました。

//誰かを紹介するfunction...を返すfunction
function introduceSomeone(who){
   //ここでの戻り値はfunction
   return function(description){
      //上位の引数であるwhoも参照できるのがポイント
      //詳しくは「クロージャ」っていう単語でググって下さい。。。
      WScript.echo(who + " is " + description + ".");
   }
}


//"Alex"について紹介するfunctionが格納される
var introduceAlex = introduceSomeone("Alex");

//以下、Alexについての紹介
introduceAlex("a guiterist");// => "Alex is a guiterist."
introduceAlex("living in Finland");// => "Alex is living in Finland."
introduceAlex("a member of the heavy metal band called Children Of Bodom"); //=> "Alex is a member of the..."(略)

//こういう風に呼んでも結果は同じ
introduceSomeone("Alex")("the main composer of his band");// => "Alex is the main composer of his band."

以上、Alexのfunctionを返すfunctionの紹介でした。
要は、「複数の引数を取るけど、一回決めた引数は使いまわしたいfunction」に適用すると便利です。
毎回毎回引数を指定するのが面倒・・・というのもありますが、本筋は余計なバグを防止することじゃないでしょうか。
例えば、コピペをミスったりとか、他の処理から間違えて値を更新してしまったりとか。。。
上記の例のintroduceAlexを使っている限り、他の処理が何をやっていてもwhoが"Alex"であることが保障されるのがポイントです。
非同期とか分散処理をやっていても安全に使えるのがいいですね。

javascriptとfunction型 その2

functionが第一級型だということは、functionの引数にfunctionを渡すことも出来ます。

例えば,

function sayHello(name,_after) {
 WScript.echo("Hello," + name + "!");

  //_afterに渡されたfunctionを呼ぶ
  //ただ、_afterがあるかどうかもそれがfunctionかも分からないので
  //一応条件分岐
  if(_after && typeof(_after) == "function"){
     _after(name); //ここではnameで渡された値をそのままスルー
  }
}



//単にnameを元にechoするだけのfunction
function sayPleaseWelcome(name) {
 WScript.echo("Please welcome " + name + "!");
}

//こちらは_afterを指定してないので、単にsayHelloを実行
sayHello("Tetsuya"); //=>"Hello,Tetsuya!"

//_afterにsayPleaseWelcomeを指定しているので、
//sayHelloが呼ばれた後にsayPleaseWelcomeが呼ばれる
sayHello("Tetsuya",sayPleaseWelcome); //=> "Hello,Tetsuya!" => "Please welcome Tetsuya!"
のようにcallbackイベントを作るときなんかに使います。

この例ではsayHelloに渡されたnameをそのまま_afterに渡していますが、例えば最初のfunctionでなんらかの処理をした結果を_afterの引数として渡してあげるともっと使い勝手が良いです。
めんどくさいのでコードは書きませんが、ajaxなんかの非同期処理がバンバン出てくるときに使うと便利ですね。

ここでは、上のコードをもうちょっといじって遊んでみます。
例えば、私、Tetsuyaが嫌われている場合のソースコード。
他の人は歓迎しますが、Tetsuyaだけは嫌いなので出て行って欲しいのです。。。
でも、大人としてちゃんと挨拶だけはしてくれます。

//最初の挨拶
function sayHello(name,_after) {
  WScript.echo("Hello," + name + "!");
  if(_after && typeof(_after) == "function"){
      _after(name);
  }
}

//歓迎すべき人への対応
function sayPleaseWelcome(name) {
   WScript.echo("Please welcome " + name + "!");
}
//好ましく無い人への対応
function sayGetOut(name) {
   WScript.echo("Get out of here," + name + "!");
}

//最初の挨拶はするけど、その後の対応は人による
function userComing(name){
   if(name == "Tetsuya"){
      //Tetsuyaだけは出て行って欲しい
      sayHello(name,sayGetOut);
   }else{
      //他の人は歓迎
      sayHello(name,sayPleaseWelcome);
   }
}



//Tetsuyaが来た場合
userComing("Tetsuya");// => 「出て行け」ってゆわれる(涙)

//Taroが来た場合
userComing("Taro");// => 歓迎される(^ o ^) 

javascriptとfunction型 その1

FaceBookにも書きましたが、javascriptは「functionが第一級型」「すべてが連想配列」ということが腑に落ちるようになるとすごくおもしろくなります。 なので、今回は「functionが第一級型」についてちょっと解説。

第一級型ってなんぞやっていうのはWikipediaでも見てもらうとして、 要するに、functionもstringやboolと同じように、自由に変数・引数・戻り値として使えるということですね。

例えば、これはごく初歩的なfunctionの使い方

function sayHello(name) {
   return "Hello," + name + "!";
}

WScript.echo(sayHello("Tetsuya"));// => "Hello,Tetsuya!"

では、(あんまり意味ないけど)このsayHelloっていう関数を変数に代入してみます。

function sayHello(name) {
   return "Hello," + name + "!";
}

//WScript.echo(sayHello("Tetsuya"));// => "Hello,Tetsuya!"

var _say = sayHello; // _sayにsayHelloというfunctionを代入
WScript.echo(_say("Tetsuya")); // => "Hello,Tetsuya!"(上でコメントアウトした行とまったく同じ)

このようにfunction型も普通に変数に格納することが出来て、格納した変数に()をつけてあげることで呼び出すこともできます。

ちなみに、

function sayHello(name) {
   return "Hello," + name + "!";
}

WScript.echo(typeof(sayHello)); //=> "function"
WScript.echo(typeof(sayHello()));//=> "string"
このようにtypeofで型を調べると、
  • sayHello("()"を付けない)=>function型
  • sayHello()("()"を付ける)=>string型(関数が実行されてreturnで返した値が返る)
というのが分かりますね。


もちろん、上記の例はあんまり意味の無いコードなので、「だからどうした!?」って言いたい気持ちは分かります(笑)
でも、この特性をうまく使うと面白いことができるんです。続きは次回。

初ブログ

眠れないのでブログ初めてみた。
FaceBookとかだと入力できる行数が少ないので。。。長々と語るのが好きなオタクにはちょうどいいかと。

ちなみにタイトルは私が好きなもの、
メタル=パワーコード、プログラミング=ソースコード
を表しています。もちろん、chordとcodeをかけたダジャレでもあります。

話題はやっぱりそのふたつになるかな。。。

でも、なるべくプログラミング系の話題を書いて、
forkwellとかで褒められたい。。。