🤐
クロージャって何のためにあるん?(JavaScript)
記事の目的
ふと「そうえいばクロージャって何のために存在するんだっけ?」と思ったので、備忘録がてら簡単にまとめました。
そのうえで、私と同じようにクロージャの必要性がよくわからない人の一助になれればと思い、記事にしました。
この記事で得られること
- クロージャってなんのためにあるん?を解決できるかも
- クロージャって何?を少し解決できるかも
結論
クロージャの最大のメリットは、グローバルの汚染を防止し、コードの保守性を高めること。
クロージャとは
関数内で特定の変数を参照し続けることで、関数が状態を持てる仕組みのことです。
JavaScriptはメモリ解放にガベージコレクションを採用しているため、関数内で変数を参照し続ける限りはメモリの状態を保持します。
そのため、変数のデータが初期化されることなく残り続け、あたかも状態を保持しているかのように振る舞います。
const createCounter = () => {
let count = 0;
return function increment() {
// `increment`関数は`createCounter`関数のスコープに定義された`変数`count`を参照している
count = count + 1;
return count;
};
};
// createCounter()の実行結果は、内側で定義されていた`increment`関数
const myCounter = createCounter();
// myCounter関数の実行結果は`count`の評価結果
console.log(myCounter()); // => 1
console.log(myCounter()); // => 2
クロージャは新しい関数を定義する
また、クロージャ関数は実行するたびに、新たな関数が定義されます。
そのため、クロージャ関数を異なる変数に代入した際は、それぞれ異なる状態(データ)を保持します。
関数を製造する工場のような働きを持つことから、このことは、関数ファクトリともよばれるらしいです。
const createCounter = () => {
let count = 0;
return function increment() {
// 変数`count`を参照し続けている
count = count + 1;
return count;
};
};
// countUpとnewCountUpはそれぞれ別のincrement関数(内側にあるのも別のcount変数)
const countUp = createCounter();
const newCountUp = createCounter();
// 参照してる関数(オブジェクト)は別であるため===は一致しない
console.log(countUp === newCountUp);// false
// それぞれの状態も別となる
console.log(countUp()); // => 1
console.log(newCountUp()); // => 1
クロージャを使って何が嬉しいのか
本表題の1つの答えとしては以下のとおりです。
- グローバル環境を汚さないで済む
クロージャを使用するとグローバル汚染を防ぐことができます。つまり、保守性の高いプログラムを書くこといができるということです。
クロージャの特性を使用することで静的スコープに閉じられた変数を参照できるため、無駄なグローバル変数を定義して、グローバル環境を汚さずに済みます。
まとめ
- クロージャとは、関数内で特定の変数を参照し続けることで、関数が状態を持てる仕組みのこと。
- クロージャは呼び出す度に、新たな関数を定義する関数ファクトリ。
- クロージャを使用することで、グローバル汚染を防ぐことができ、保守性が高まる。
以上です。
間違い・補足等ありましたら、コメントで教えてもらえたら嬉しいです。
ありがとうございました。
参考
関数とスコープ
クロージャ - JavaScript | MDN
真面目に JavaScript のクロージャを解説する - プログラムを自動生成したい
Discussion