序章

この記事では、クロージャとは何か、JavaScriptがクロージャの恩恵を受ける理由の基本について説明します。

前提条件

この記事をフォローしたい場合は、次のものが必要になります。

  • JavaScript変数、関数、スコープ、およびコールバックに精通していること。

クロージャーの定義

クロージャは、変数によって保持される永続的なスコープとして定義できます。 JavaScriptやRubyなどの言語はクロージャをサポートしています。これにより、プログラミングブロックが実行された後でも、変数が親スコープを参照できるようになります。これらの変数がどこかに参照を持っている限り、クロージャは存在します。

次のクロージャの例を考えてみましょう。

function outerFunction() {
 let delayed = veryLongOperation();

 let innerFunction = function() { someCallback(delayed); }
}

The innerFunction 親スコープ要素にアクセスできる関数です-のように delayed 物体。

クロージャーの使用

クロージャーとは何かを見てきましたが、なぜそれらが役立つのでしょうか。

JavaScriptは、実行に関しては非同期にすることができます。 操作が完了すると、コールバックを使用する必要があります。 このコールバックは、呼び出し元/親と同じ実行コンテキストで実行する必要があります。 つまり、親が利用できる変数や関数はすべて、コールバックでも利用できるようにする必要があります。 これらのコールバックにクロージャがない場合は、必要なスコープメンバーを手動でバインドする必要があります。

クロージャーは、バックグラウンドでこれを処理することにより、私たちの生活をはるかに楽にします。 関数内に関数がある場合、内部関数はその存続期間を通じてスコープメンバーにアクセスできます。

次のクラス定義の例を考えてみましょう。

let classExample = function () {
  let randomNumber = Math.floor(Math.random() * 10);

  return function() {
    console.log(randomNumber);
  }
}

内部関数のスコープチェーンは、のメンバーを含むように拡張されています classExample 関数。

クロージャーが作用するもう1つの例は、カリー化中です。 カリー化は、アリティを減らすために複数の関数を返すプロセスです。 これは、関数型プログラミングのパラダイムで使用され、状態の変化を減らします。

クロージャーをカリー化と一緒に使用して、JavaScriptクラスのプライベートメンバーを紹介できます。

function curryingExample() {
  let message = "Hello.";

  return {
    getMessage: function() { console.log('private message', message); }
  };
}

新しいを作成します curryExample() 実例:

let curry = new curryingExample();

アクセスを試みます message:

console.log('undefined message', curry.message);

いつ console.log(curry.message); 実行する値は次のようになります undefined.

使用してみてください getMessage():

curry.getMessage();

いつ curry.getMessage(); 実行すると、値は次のようになります "Hello.".

結論

クロージャーはJavaScriptの非常に微妙でありながら強力な機能であり、クロージャーを理解することは、真剣なJavaScript開発者になるための非常に重要なステップです。

これについては、カイルシンプソンのClosuresに関する優れた記事で詳しく説明されています。