JavaScriptにおけるグローバルカウンター変数

変数 num を関数の外に出し、 グローバル変数にしてみましょう:

javascriptlet num = 1; // グローバル変数

function test() {
  return function() {
    console.log(num);
    num++;
  };
}

この場合、返されるすべての関数が このグローバル変数を変更するため、 カウンターは互いに依存して動作します:

javascriptlet num = 1;

function test() {
  return function() {
    console.log(num);
    num++;
  };
}

let func1 = test(); // 最初のカウンター
func1();  // 1 を出力
func1();  // 2 を出力

let func2 = test(); // 2番目のカウンター
func2();  // 3 を出力
func2();  // 4 を出力

では、なぜ前のコードは独立したカウンターを作ったのでしょうか? そのコードを再掲します:

javascriptfunction test() {
  let num = 1;
  
  return function() {
    console.log(num);
    num++;
  };
};

理由は、変数 num が関数 test 内の ローカル変数だからです。したがって、 test が呼び出されるたびに、 独自のローカル変数が生成されます。

そのため、返される各関数は、 それぞれの test 関数のローカル変数を参照します。 これがまさに、動作の独立性を実現する方法です。

一方、num をグローバル変数にした場合も、 クロージャにはなります。ただし、返される関数の レキシカル環境はすべて同じ変数 num を参照するため、 この変数に対する変更はすべての関数で共有されます。

Задание 1

コードを実行せずに、コンソールに何が出力されるか判断してください:

javascriptlet counter = 0;
    
function test() {
  return function() {
    console.log(counter);
    counter++;
  };
}

let func = test;

let func1 = func();
let func2 = func();
func1();
func2();
func1();
func2();
Задание 2

コードを実行せずに、コンソールに何が出力されるか判断してください:

javascriptfunction test() {
  let counter = 0;
  
  return function() {
    return function() {
      console.log(counter);
      counter++;
    };
  };
}

let func = test()();

let func1 = func;
let func2 = func;
func1();
func2();
func1();
func2();
Задание 3

コードを実行せずに、コンソールに何が出力されるか判断してください:

javascriptfunction test() {
  let counter = 0;
  
  return function() {
    return function() {
      console.log(counter);
      counter++;
    };
  };
}

let func = test();

let func1 = func();
let func2 = func();
func1();
func2();
func1();
func2();