JavaScript のクロージャーとは何ですか? また、いつ使用するのですか?


Can you explain what is a closure in JavaScript?



これは間違いなく、フロントエンドの面接で最も人気のある質問の 1 つです. JavaScript の面接ラウンドで、この質問に直面した可能性は 99% あります.

そしてそれは正当化されます.

クロージャーは非常に重要な概念であるため、気付かないうちにすでに使用している可能性があります.

クロージャーを含む実際の開発シナリオをいくつか見ていきますが、最初に、クロージャーが実際に何であるかを理解しましょう.

JavaScript のクロージャーとは何ですか?



クロージャーの全体的な概念は、スコープに基づいています.また、スコープは、プログラム内の変数または関数にアクセスできる場所を決定します.それと同じくらい簡単です.スコーピングは、コードのどの部分が何にアクセスできるかを定義します.以下の例を見て、スコーピングをよりよく理解してください.

// Variable a has access everywhere because
// it is defined globally.
var a = 10;

function print() {
  console.log(a);

  // Variable b has access inside this function because it is defined inside
  // the function. If b is accessed outside function print, it will give an error.
  var b = 20;

  if (true) {
    // Variable c has access inside this if block only because it
    // is defined inside the block using let.
    // If c is accessed outside the if block, it will give an error.
    let c = 30;

    console.log(a, b, c);
  }

  // This line will give an error as we are trying to
  // access c outside its scope
  console.log(c);
}

console.log(a);

print();


スコープについて明確になったので、JavaScript がスコープをどのように処理するかを見てみましょう.

JavaScript はレキシカル スコープに従います.これは、変数にアクセスするときに、変数が現在のスコープ/ブロックで見つからない場合、JavaScript が親スコープをチェックすることを意味します.

それでも見つからない場合、JavaScript は親の親スコープをチェックします.このようにして、その変数はスコープ階層までずっと検索されます.見つからない場合、JavaScript はエラーをスローします.

前のコード スニペットの場合、 a の変数 if block にアクセスすると、そこには存在しません.そのため、JavaScript はグローバル スコープまで進み、 a の値を取得します.

これで、クロージャを学ぶための十分な根拠ができました.

A closure is function bundled with its lexical scoping.



簡単に言えば、関数がそのスコープ外から変数にアクセスしている場合、関数とそれらの変数はクロージャを形成します.

なぜそれらは閉鎖を形成するのですか? —その関数が実行されると、親スコープの実行が終了しても、それらの変数が必要になるためです.これは通常、関数から関数を返すときに発生します.

これをよりよく理解するために、例を見てみましょう.

function outerFunction() {
  var outerVariable = 'I was in outer scope and now I am in closure with innerFunction';

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

const returnedFunction = outerFunction();
returnedFunction();


ここで何が起こっているかを分析しましょう.
  • outerVariableouterFunction のスコープで宣言されています.
  • innerFunctionouterVariable を使用し、実行せずに返されます.
  • 行番号 11 が実行されると、outerFunction のスコープが消失します.
  • しかし、 returnedFunction を実行すると、まだ outerVariable の値が出力されます
  • それで何が起こったのか: innerFunction は、一緒にバンドルされた外側のスコープからの変数と共に返されました.つまり、Closure が返されました.

  • それでおしまい!!クロージャについて知っておく必要があるのはこれだけです.もちろん、他にも複雑な例がいくつかあります.今はそれらを理解しやすくなっています.

    クロージャーに関する重要な注意事項の 1 つは、クロージャーが親スコープからの変数への参照を保持することです.値ではありません.そのため、クロージャーを使用する関数は、値を変更して更新された値を取得できます.これは、以下にリストされている他の実際の例で役立ちます.

    クロージャーの実世界への応用



    前述したように、気付かないうちにクロージャーを使用している可能性があります.以下は、閉鎖がより良い解決策である場合に私が遭遇したいくつかのユースケースです.
  • Writing your own debounce function
  • Writing your own throttle function
  • プライベート変数の実装
  • 状態の維持

  • この記事は originally published here でした.このような興味深い読み取りについては、 visit my blog .