さわらブログ

さわら(@xhiroga)の技術ブログ

【棚卸し】匿名関数とラムダ式、クロージャー、カリー化

調べるうちに何となく分かってきたので、自分の言葉で整理。

背景

タイトルに挙げた用語をうまく説明できなかったので調査した。
もし誤りがあれば、コメントで指摘していただけると助かります。

要約

関数がオブジェクトである(=自分のローカル変数を持てる)言語において、関数名を持たない関数を匿名関数 / ラムダ式という。
Javaの場合、抽象化されたメソッドを一つだけもつ「関数型インターフェース」を処理中に継承・クラス化したものを関数オブジェクトのように扱っている。

クロージャーは、自分自身のローカル変数として自分が定義された式の中の変数を参照する関数のこと。定義してくれた式が終了しても変数への参照を持ち続ける=閉じ込める、でクロージャー。
カリー化は、複数の引数をとる関数を一つの引数を取る関数の組み合わせで表現すること。カリーは数学者の名前から取っている。

関数式

JavaScriptでは、関数を定義するために「関数宣言」と「関数式」の二通りがある。後者では関数名を省略することができ、そうしてできた関数は匿名関数になる。
関数式の場合は、定義と同時にその関数を使うことができる。これを即時関数という。

(
  function() {
    console.log("hello");
  }
) ();

クロージャ

理解するまでいろんなブログを参照したが、結局MDNのドキュメントが一番分かりやすかった。
次回からは調べ物はここを真っ先に見るぞ。

クロージャーについて解説しているブログで、誤っていると思われるものがあった。 dqn.sakusakutto.jp

気になったのは、

問題: 呼び出すたびに、1,2,3,...を返すような関数 f( )を定義せよ。
f();  //  1 
f();  //  2
f();  //  3

クロージャを使うと解けるって記事なんだけど、別に使わなくても解けるよね?以下の通り。

f = () => {
  if (typeof x == 'undefined') {
    x = 0;
  }
  x = x + 1;
  console.log(x);
}

どや。

カリー化

どこで見たか忘れたんだけど、良い例があった。

function devisor(x) {
  var devide = (y) => {
    return x/y;
  };
  return devide;
};

half_five = devisor(5)(2);
one_third = devisor(1)(3);

参考文献

関数と関数スコープ - JavaScript | MDN

クロージャ - JavaScript | MDN

アロー関数 - JavaScript | MDN

クロージャ - Wikipedia