1. ホーム
  2. functional-programming

[解決済み] クロージャ」とは何ですか?

2022-03-19 15:43:59

質問

Curryingについて質問したところ、クロージャについて言及されました。 クロージャとは何ですか?キュアリングとどのような関係があるのでしょうか?

どのように解決するのですか?

変数スコープ

ローカル変数を宣言すると、その変数にはスコープが設定されます。一般に、ローカル変数は宣言したブロックや関数の中でのみ存在します。

function() {
  var a = 1;
  console.log(a); // works
}    
console.log(a); // fails

ローカル変数にアクセスしようとすると、ほとんどの言語は現在のスコープから探して、ルートスコープに到達するまで親のスコープを上がっていくんだ。

var a = 1;
function() {
  console.log(a); // works
}    
console.log(a); // works

ブロックや関数が終了すると、そのローカル変数は不要になり、通常はメモリから吹き飛んでしまいます。

通常、私たちはこのような仕組みを想定しています。

クロージャは永続的なローカル変数のスコープです。

クロージャとは、ローカル変数を保持する永続的なスコープで、コードの実行がそのブロックの外に出た後でも保持します。クロージャをサポートする言語(JavaScript、Swift、Ruby など)では、変数が宣言されたブロックが実行を終えた後でも、そのブロックや関数への参照をどこかに残しておけば、スコープ(その親スコープを含む)への参照を保持することができるようになります。

スコープオブジェクトとそのすべてのローカル変数は関数に関連付けられ、その関数が永続化する限り永続化されます。

これによって、関数のポータビリティが実現します。関数が最初に定義されたときにスコープ内にあった変数は、たとえその関数をまったく別のコンテキストで呼び出したとしても、後でその関数を呼び出すときにはまだスコープ内にあることが予想されます。

例えば

ここで、JavaScriptによる実にシンプルな例で説明します。

outer = function() {
  var a = 1;
  var inner = function() {
    console.log(a);
  }
  return inner; // this returns a function
}

var fnc = outer(); // execute outer to get inner 
fnc();

ここでは、関数の中に関数を定義しています。内側の関数は、外側の関数のすべてのローカル変数にアクセスできるようになり、その中には a . 変数 a は内部関数のスコープ内です。

通常、関数が終了すると、そのローカル変数はすべて吹き飛ばされます。しかし、内部関数を返して、それを変数 fnc の後にも残るように outer が終了しました。 のときにスコープ内にあったすべての変数が inner が定義されたときにも持続します。 . 変数 a はクローズオーバーされている -- クロージャの中にある。

なお、変数 a は完全にプライベートで fnc . これは、JavaScriptなどの関数型プログラミング言語において、プライベート変数を作成する方法である。

ご推察の通り、私が fnc() の値が表示されます。 a であり、それは "1" である。

クロージャのない言語では、変数 a はガベージコレクションされ、捨てられたはずです。 outer が終了しました。fncを呼び出すとエラーが発生します なぜなら a はもう存在しない。

JavaScriptでは、変数 a なぜなら、変数のスコープは関数が最初に宣言されたときに作成され、その関数が存在し続ける限り存続するからです。

a のスコープに属します。 outer . のスコープは inner のスコープへの親ポインタを持っています。 outer . fnc を指す変数です。 inner . a が続く限り続く。 fnc が持続する。 a はクロージャーの中にある。

さらに読む(見る)

を作りました。 YouTube動画 を、実際の使用例を交えてご紹介します。