CodeGym /コース /Frontend SELF JA /クロージャ

クロージャ

Frontend SELF JA
レベル 37 , レッスン 5
使用可能

6.1 クロージャの概念

クロージャはJavaScriptで最も強力かつ重要な概念の一つだよ。これを使うと、関数が実行された後でもその レキシカルスコープを記憶できるんだ。この講義では、クロージャの概念、特徴、そしてさまざまな使用例を見ていこう。

JavaScriptのクロージャとは、関数とその関数が宣言されたレキシカルスコープの組み合わせのことだよ。 クロージャを使うと、関数は外側のスコープの変数や他の関数にアクセスできるんだ。

クロージャの主な特徴:

  1. レキシカルスコープ: 関数が宣言された時のコンテキストで、その時点でアクセス可能なすべての変数を含む。
  2. コンテキストの保存: クロージャ付きの関数は、外側の関数が終了した後でも、外側のスコープの変数にアクセスできる。

6.2 クロージャの例

例 1: シンプルなクロージャ

この例では、innerFunction()outerVariableを外側のスコープから取得できるんだ。 outerFunction()が終了した後もね。

JavaScript
    
      function outerFunction() {
        let outerVariable = 'I am from the outer function';

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

      const closure = outerFunction();
      closure(); // 結果: I am from the outer function
    
  

例 2: クロージャを使ったカウンター

この例では、カウンター関数がcountの値を保持して、呼び出されるたびにそれを増加させるんだ。

JavaScript
    
      function createCounter() {
        let count = 0;

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

      const counter = createCounter();

      console.log(counter()); // 結果: 1
      console.log(counter()); // 結果: 2
      console.log(counter()); // 結果: 3
    
  

例 3: ループ内のクロージャ

クロージャは、ループ内の変数の値を保存するためによく使われるよ。

この例では、配列arrの中の各関数が、それぞれの作成時点での変数iの値を letのブロックスコープのおかげで記憶しているんだ:

JavaScript
    
      function createArrayWithClosures() {
        let arr = [];

        for (let i = 0; i < 3; i++) {
          arr[i] = function() {
            console.log(i);
          };
        }
        return arr;
      }

      const closures = createArrayWithClosures();

      closures[0](); // 結果: 0
      closures[1](); // 結果: 1
      closures[2](); // 結果: 2
    
  

6.3 クロージャの高度な使用シナリオ

例 1: 部分適用 (partial application)

クロージャを使うと、一部の引数を固定した部分適用関数が作れるんだ。

この例では、multiply()関数が引数aを固定して、そのbを掛け算する関数を返すんだ。

JavaScript
    
      function multiply(a) {
        return function(b) {
          return a * b;
        };
      }

      const double = multiply(2);
      console.log(double(5)); // 結果: 10
      console.log(double(10)); // 結果: 20
    
  

例 2: データの隠蔽 (data hiding)

クロージャは、プライベートな変数とメソッドを作るために使われることもあるよ。

この例では、_name_ageの変数はプライベートで、オブジェクトのメソッドを通じてのみアクセスできるんだ:

JavaScript
    
      function createPerson(name, age) {
        let _name = name;
        let _age = age;

        return {
          getName: function() {
            return _name;
          },
          getAge: function() {
            return _age;
          },
          setName: function(newName) {
            _name = newName;
          },
          setAge: function(newAge) {
            _age = newAge;
          }
        };
      }

      const person = createPerson('John', 30);
      console.log(person.getName()); // 結果: John

      person.setName('Jane');

      console.log(person.getName()); // 結果: Jane
      console.log(person.getAge());  // 結果: 30
    
  

例 3: メモ化 (memoization)

メモ化は、同じ入力値での計算を避けるために、関数の結果を保存する最適化技術だよ。

この例では、memoize()関数が、関数fn()の計算結果をキャッシュするためにクロージャを使用しているんだ:

JavaScript
    
      function memoize(fn) {
        const cache = {};

        return function(...args) {
          const key = JSON.stringify(args);
          if (cache[key]) {
            return cache[key];
          }
          const result = fn(...args);
          cache[key] = result;
          return result;
        };
      }

      function slowFunction(num) {
        console.log('Computing...');
        return num * 2;
      }

      const memoizedFunction = memoize(slowFunction);

      console.log(memoizedFunction(5)); // 結果: Computing... 10
      console.log(memoizedFunction(5)); // 結果: 10 (キャッシュから取得した結果)
    
  
1
アンケート/クイズ
日付、タイマーとリテラル、レベル 37、レッスン 5
使用不可
日付、タイマーとリテラル
日付、タイマーとリテラル
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION