JavaScriptの愉快な函数たち

函数もデータとして扱われるオモシロ言語のJavaScript. 本稿では,そんなJavaScriptで書くことのできる愉快な函数たちを少し紹介します. まずは函数がデータとして扱われることを見てみます. Webブラウザを開いて,開発者ツール(Webインスペクタ)を立ち上げましょう. コンソールにJavaScriptコードを入力することで,カンタンに動作を確認できます. そこはもうサンドボックスです.

函数はデータ

函数はデータなので,変数へ代入することが出来ます. 次に2つの函数定義を示しますが,この2つは全く同じ意味になります. 他の手続き型言語と似た構文で定義するか,はたまた無名函数を変数へ代入するか,見た目の違いです.
function sum1(a, b) {return a+b}
var sum2 = function(a, b) {return a+b}
上2つの函数をtypeofで確認すると,両方ともfunctionとして定義されていることが分かります.
実行結果

自分を上書き

函数はデータなので,変数へ代入することが出来ると言いました. この性質を利用して,自分自身を上書きする函数も作れます. 次のコードを実行すると,fという名の函数が定義されます. この函数を実行すると,alertが表示され,次いでfに無名函数が代入されます. この代入先であるfは今現在実行している函数自身です. なので,もう一度fを実行すると,今度は代入された無名函数の動作になります. オブジェクト指向で言うコンストラクタのように,最初の動作だけ別の処理を行いたい函数はこのように書けば良いわけです.
function f() {
  alert("first time!");
  f = function() {
    alert("hello")
  }
}
最初の実行時だけ"first time!"とアラートが出ます. 後は何回実行しても"hello"になります.
実行結果

函数を返す函数

函数を引数として渡すことが出来ますが,函数を戻り値として返すことも出来ます. 函数のカリー化という名でも親しまれている手法です. 手順をひとつづつ追うと混乱してしまうので,もう手法として形で覚えてしまいましょう. 使いこなせるようになってから詳しく手順を追っていっても遅くはありません. 函数を戻り値として返すことで,複数個の引数を別々のカッコで括ることが出来るようになります. 作り方はカンタンです. 例えば2つの引数を受けたいならば,まずはいつも通りに函数をつくって,その戻り値を無名函数にします(下のコードではsum函数の戻り値が無名函数). 2つの函数が入れ子になれば,引数は2つ渡せます. それぞれの函数には1つづつ仮引数を用意します(下のコードではab). 一番内側の函数の戻り値を最終的な結果とします(下のコードではa+b). ちなみに,入れ子は幾つでも作れますが,実用性の面では2つまででしょう.
function sum(a) {
  return function(b) {
    return a+b
  }
}
上のコードをsum(2)(3)として実行すると5が帰ってきます. これは一番内側の函数の戻り値a+bの結果ですね. 少し突っ込んで話すと,このカリー化によって次のようなことが可能になります.
var add_one = sum(1);
add_one(8);
add_one(8)の結果は9です. sum(1)のように,先に引数をひとつだけ渡して,その結果である戻り値(函数)をadd_oneという変数へ代入したわけです. このadd_oneに引数を渡すと,sum(1)に引数をもうひとつ渡すのと同じ意味になるので,add_one(8)sum(1)(8)と同じ結果が返ってくるわけです. カリー化によって,引数を異なるタイミングでひとつづつ渡すことが出来るようになるのです. 函数がデータであることを上手く使った例ですね.
実行結果

定義した直後に実行する函数

JavaScriptファイルが読み込まれたら直ぐに動作を実行させたい函数がある場合,函数を定義する文と函数を実行する文,両方を書く必要があります. というのも,C言語で言うmain函数のように勝手に実行される函数がJavaScriptには無いからです. そんなJavaScriptでも定義と同時にそれを実行させることが出来ます. 下のコードのように実行させたい函数定義全体を丸カッコで括り,そのカッコの後ろにもうひとつ丸カッコのペア(引数用のカッコ)を置く. これだけで,定義と実行,両方を行う函数定義を書くことが出来ます.
(function greeting(message) {
    alert(message)
}) ("HELLO!")
最後のカッコは実引数ですので,中身の"HELLO!"がmessage引数へと代入されるのです. カッコで括ってあげるだけで自発的になる函数定義. なんとも面白い言語ですね.
実行結果
2619099332932760769 http://www.storange.jp/2015/05/javascript.html http://www.storange.jp/2015/05/javascript.html JavaScriptの愉快な函数たち 2015-05-24T13:50:00+09:00 http://www.storange.jp/2015/05/javascript.html Hideyuki Tabata 200 200 72 72