【5分でわかる】JavaScriptのクロージャ、スコープとは?

javascript
目次

はじめに

JavaScriptは初学者にとって最初は少し複雑に感じられるかもしれませんが、心配しないでください!
今回は、JavaScriptの基本的な概念である「クロージャ」と「スコープ」に焦点を当て、わかりやすく解説します。


新人:グラミちゃん

こんにちは、プロくん!最近、JavaScriptのコードを読んでいて「クロージャ」と「スコープ」っていう言葉を見かけたんだけど、これって何なの?

エンジニア:プロくん

こんにちは、グラミちゃん!それは重要な概念だよ。まずはスコープから説明しようか。

詳しく勉強する

JavaScript スコープとは?

JavaScriptにおけるクロージャ(Closure)とスコープ(Scope)は、プログラミングにおいて非常に重要な概念であり、これらを理解することは効果的なコードの記述において大きな影響を与えます。初心者向けに、クロージャとスコープの基本的な理解を提供します。

スコープの基本

スコープは、変数が有効である範囲を定義します。JavaScriptには2つの主要なスコープがあります。

  1. グローバルスコープ(Global Scope): プログラム全体でアクセス可能なスコープ。
  2. ローカルスコープ(Local Scope): 特定の関数内でのみアクセス可能なスコープ。

変数がどのスコープに属しているかによって、その変数へのアクセスが異なります。例えば:

// グローバルスコープの変数
let globalVar = "I'm global";

function exampleFunction() {
    // ローカルスコープの変数
    let localVar = "I'm local";
    console.log(globalVar); // グローバル変数にアクセス可能
    console.log(localVar);  // ローカル変数にアクセス可能
}

exampleFunction();
console.log(globalVar); // グローバル変数にアクセス可能
// console.log(localVar); // エラー - ローカル変数にアクセス不可

javascript スコープ わかりやすく説明

エンジニア:プロくん

スコープは、変数がどこで有効かを定義するものだよ。
変数が宣言された場所によって、その変数がどこからアクセスできるかが変わるんだ。

新人:グラミちゃん

ああ、なるほど。スコープって、変数の有効範囲を指すんだね。

エンジニア:プロくん

そうだね。例えば、次のコードを見てみよう。

function exampleFunction() {
  let x = 10; // この変数xはこの関数内でのみ有効
  console.log(x);
}

exampleFunction();
console.log(x); // エラー!xはここで未定義

この例では、変数 xexampleFunction の中で有効であり、関数の外ではエラーになります。


Javascriptのクロージャの説明と例題

新人:グラミちゃん

スコープは理解したよ!では、クロージャって何?

エンジニア:プロくん

クロージャは、関数が定義された時のスコープ外の変数にアクセスできるようになる仕組みだよ。これによって、関数がスコープ外の変数を覚えている状態が生まれるんだ。

新人:グラミちゃん

なるほど、関数が覚えているってことは、後でその変数にアクセスできるってこと?

エンジニア:プロくん

そうだね。例えば、次のコードを見てみよう。

function createCounter() {
  let count = 0;

  return function() {
    count++;
    return count;
  };
}

let counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

この例では、createCounter 関数がクロージャを返し、そのクロージャ内で変数 count にアクセスしています。これにより、counter を呼び出すたびに count が保持され、増加していく様子が確認できます。

詳しく勉強する

クロージャの基本

クロージャは、関数がその外部スコープの変数にアクセスできるようになる概念です。関数が実行された後も、その関数が定義された時点でのスコープにアクセスできるという特性がクロージャによって実現されます。

function outerFunction() {
    let outerVar = "I'm outer";

    function innerFunction() {
        console.log(outerVar); // outerFunctionのスコープにアクセス可能
    }

    return innerFunction;
}

let closureExample = outerFunction();
closureExample(); // "I'm outer"

この例では、innerFunctionouterFunction のスコープにアクセスでき、outerVar を利用できています。outerFunction が実行されると、innerFunction が返され、それを closureExample でキャッチして実行することで、outerVar へのアクセスが可能です。

クロージャの応用例

プライベート変数の模倣: クロージャを使用して、外部からアクセスできないプライベート変数を模倣できます。

function counter() {
    let count = 0;

    return function() {
        count++;
        console.log(count);
    };
}

let increment = counter();
increment(); // 1
increment(); // 2

count 変数は counter 関数のスコープに閉じ込められており、外部から直接アクセスすることができません。

イベントハンドラでの利用: イベントハンドラ内で変数の状態を保持するためにクロージャが使用されることがあります。

function createButton() {
    let count = 0;
    let button = document.createElement("button");

    button.textContent = "Click me";
    button.addEventListener("click", function() {
        count++;
        console.log("Button clicked " + count + " times");
    });

    return button;
}

let myButton = createButton();
document.body.appendChild(myButton);

この例では、ボタンがクリックされるたびに count の値が保持され、クリックされた回数がコンソールに表示されます。

クロージャとメモリ管理

注意が必要な点として、不要なクロージャがメモリリークを引き起こす可能性があります。クロージャが外部スコープの変数を参照している場合、そのクロージャが不要になってもガベージコレクションによって解放されない可能性があります。これによりメモリリークが発生するため、適切にクロージャを使用する際は注意が必要です。


まとめ

新人:グラミちゃん

なるほど、スコープとクロージャって大事なんだね。これでちょっとだけ理解できた気がするよ

エンジニア:プロくん

よかったね、グラミちゃん!これらの概念を理解することで、より良いコードを書くことができるようになるよ。


結論

JavaScriptのクロージャとスコープは、初めて聞くと難しく感じるかもしれませんが、しっかり理解することでプログラミングの世界が広がります。是非、実際のコードで試してみてください。それでは、Happy Coding!

目次