JavaScript - クロージャ

こんにちは、将来のプログラミングスーパースターたち!? 今日は、JavaScriptのクロージャの世界に楽しい旅に出発しましょう。その名前が少し脅威に思えるかもしれませんが、心配しないでください。このチュートリアルが終わるまでには、クロージャの専門家になることを約束します!お気に入りの飲み物を持って、リラックスして、一緒に潜りましょう!

JavaScript - Closures

クロージャとは?

あなたが魔法の箱を持っていて、その中のすべてのものを閉じても覚えておける imagine してみてください。それは、JavaScriptでのクロージャの概念とほぼ同じです!

クロージャは、外部( encapsulating )レキシカルスコープ内の変数にアクセスできる関数で、外部関数が返った後でもそのアクセスが可能です。関数が必要に応じて使える小さな変数のバックパックを持っているかのようです。

簡単な例を見てみましょう:

function outerFunction(x) {
let y = 10;
function innerFunction() {
console.log(x + y);
}
return innerFunction;
}

let closure = outerFunction(5);
closure(); // 出力: 15

この例では、innerFunction はクロージャです。outerFunction が実行終了した後でも、xy の値を「覚えています」。

レキシカルスコープ

クロージャを深く掘り下げる前に、レキシカルスコープを理解する必要があります。これは、関数が外部スコープの変数にアクセスできるという意味の派手な言葉です。

let name = "Alice";

function greet() {
console.log("Hello, " + name + "!");
}

greet(); // 出力: Hello, Alice!

ここで、greet はレキシカルスコープのおかげで name 変数にアクセスできます。greet は周囲の環境を見ることができるかのようです。

ネストされた関数

クロージャはしばしばネストされた関数に関連しています。例を見てみましょう:

function outer() {
let count = 0;
function inner() {
count++;
console.log(count);
}
return inner;
}

let counter = outer();
counter(); // 出力: 1
counter(); // 出力: 2

ここで、innerouter 内にネストされています。魔法が起きるのは、inner が外部スコープの count 変数を覚えて、outer が実行終了した後でもアクセスできるからです。

関数の返却

JavaScriptの素晴らしい機能の一つは、関数が他の関数を返却できることです。これはクロージャの鍵となる部分です。

function multiplier(x) {
return function(y) {
return x * y;
};
}

let double = multiplier(2);
console.log(double(5)); // 出力: 10
console.log(double(3)); // 出力: 6

この例では、multiplierx の値を覚える関数を返却します。この返却された関数はクロージャです。

カウンタのジレンマ

クロージャが解決できる一般的な問題を見てみましょう:

function createCounter() {
let count = 0;
return {
increment: function() {
count++;
},
getCount: function() {
return count;
}
};
}

let counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.getCount()); // 出力: 2

ここで、クロージャはプライベートな変数(count)を作成し、提供されたメソッドを通じてのみアクセスできるようにします。

例: JavaScriptのクロージャ

理解を固めるために、もっと複雑な例を見てみましょう:

function makeAdder(x) {
return function(y) {
return x + y;
};
}

let add5 = makeAdder(5);
let add10 = makeAdder(10);

console.log(add5(2));  // 出力: 7
console.log(add10(2)); // 出力: 12

この例では、makeAdderx の値を覚えるクロージャを作成します。異なる预设値で複数のアダー関数を作成することができます。

クロージャの実用的な例をもう一つ見てみましょう:

function createGreeter(greeting) {
return function(name) {
console.log(greeting + ", " + name + "!");
};
}

let greetHello = createGreeter("Hello");
let greetHi = createGreeter("Hi");

greetHello("Alice"); // 出力: Hello, Alice!
greetHi("Bob");      // 出力: Hi, Bob!

この例では、クロージャがカスタマイズされた関数を作成する方法を示しています。

クロージャの利点

クロージャにはいくつかの利点があります:

  1. データのプライバシー
  2. 関数ファクトリー
  3. ステートの保持

これらを見てみましょう:

利点 説明
データのプライバシー クロージャはプライベートな変数を作成します function counter() { let count = 0; return { increment: () => ++count, getValue: () => count }; }
関数ファクトリー プリセットパラメータで関数を作成します function multiply(x) { return (y) => x * y; }
ステートの保持 関数呼び出し間でデータを追跡します function createGame() { let score = 0; return { addPoint: () => ++score, getScore: () => score }; }

そして、みなさん!クロージャの土地を旅しました。基本的なことからもっと高度な概念までです。忘れてはならないのは、どんなスキルも練習によってマスターできるということです。すぐに理解できない場合は、がっかりしないでください。codingを続け、実験を続け、間もなくクロージャの力を自在に操るプログラミングウィザードになるでしょう!?‍♂️✨

Credits: Image by storyset