9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【JavaScript】クロージャを理解する

Last updated at Posted at 2021-09-28

はじめに

JavaScriptのクロージャの学習メモです。
誤りご指摘等あれば、気軽にコメントいただけると嬉しいです。

クロージャとは?

自分の言葉で簡単に表現してみると
「定義した関数の外側のスコープにある変数や関数を参照できる仕組み(または関数)」のこと
だと理解しました。

公式だとこのように書かれてました。
クロージャ

クロージャは、組み合わされた(囲まれた)関数と、その周囲の状態(レキシカル環境)への参照の組み合わせです。言い換えれば、クロージャは内側の関数から外側の関数スコープへのアクセスを提供します。JavaScript では、関数が作成されるたびにクロージャが作成されます。

クロージャのメリット

関数内などの変数や関数などを他のプログラムから簡単に変更されないように制御できること。

クロージャの実行サンプル

初期値の数値を引数で渡して、それをクロージャ関数(内部に定義した関数)から計算して、計算結果をコンソールに出力するサンプル。

※サンプルコードはTypeScriptで記述してます。が気にせず。

// 4つのクロージャ関数を生成して返す関数
function calcFactory(def: number) {
  // ローカル変数result: calcFactory関数のスコープ内でしか参照できない
  let result: number = def;

  // この4つの関数たちがクロージャ
  const plus = (num: number) => {
    console.log("計算前", result);
    result = result + num;
    console.log("計算後", result);
  };
  const minus = (num: number) => {
    console.log("計算前", result);
    result = result - num;
    console.log("計算後", result);
  };
  const multiply = (num: number) => {
    console.log("計算前", result);
    result = result * num;
    console.log("計算後", result);
  };
  const divide = (num: number) => {
    console.log("計算前", result);
    result = result / num;
    console.log("計算後", result);
  };

  // クロージャ関数を返す
  return { plus, minus, multiply, divide };
}

// このタイミングでクロージャが生成される 
const calc = calcFactory(10);
calc.plus(3);
calc.minus(5);
calc.multiply(8);
calc.divide(4);

コンソール出力結果
スクリーンショット 2021-09-29 8.11.14.png

このときcalcFactory関数の中でしか参照できない変数resultに計算結果を保ちながら、処理が繰り返される。
変数resultにはクロージャ関数plus minus multiply divideからしか参照できない。

const calc = calcFactory(10);
calc.plus(3);
calc.minus(5);
calc.multiply(8);
calc.divide(4);
// クロージャを経由せずにresultを参照することはできない
calc.result; // エラー

関数が作成されるたびにクロージャが作成される

公式にもこのような記述がありますが、

JavaScript では、関数が作成されるたびにクロージャが作成されます。

どういうことかコードで確認してみる。

// このタイミングでdefに10をもつクロージャが生成される
const calc = calcFactory(10);
calc.plus(3);
calc.minus(5);
calc.multiply(8);
calc.divide(4);

console.log("--------------------------------------");

// このタイミングでdefに20をもつcalcとは異なるクロージャが生成される
const calc2 = calcFactory(20);
calc2.plus(3);
calc2.minus(5);
calc2.multiply(8);
calc2.divide(4);

calcFactory関数を実行するたびに異なる(今回の場合は引数defが違う数値を渡すことにより変数resultが異なる)クロージャが生成される。

コンソール出力結果
スクリーンショット 2021-09-29 8.21.35.png

最後に

大変有益でわかりやすい記事ばかりで助かりました!ありがとうございました!

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?