LoginSignup
0
0

More than 1 year has passed since last update.

[初学者]javascriptのクロージャー

Posted at

はじめに

while文とかfor文とか~文あるけど、あれは関数なのか?の疑問から生まれたものです。
文の正体は分かりませんでした。

目次

 1.ループ文の謎
 2.ガベージコレクション? ガレージコレクションなら知ってます。
 3.静的スコープとはなんですか?
 4.クロージャー

ループ文の謎

ループ文とはご存知でしょうか?基礎で出てくるあれです。

for(let i = 0; i < 5; i += 1) {
  console.log(i);
}
// 0,1,2,3,4と出ます。

基礎の基礎のループ文。
ではあえて関数で書くとどうやって書くのかを疑問に持ちました。

let a = 0;
function A() {
  a += 1;
  console.log(a);
};

A(); //1
A(); //2
A(); //3
A(); //4
A(); //5

普通に出ますね。ではlet a = 0;を関数内に入れてみましょう。

function A() {
  let a = 0;
  a += 1;
  console.log(a);
};

A(); //1
A(); //1
A(); //1
A(); //1
A(); //1

関数内に入れたら数字が全て1になってしまいました。
私みたいな初学者には、関数の中と外なんて似たりよったりやんと思いますが結果から見ても違います。

ガベージコレクション? ガレージコレクションなら知ってます。

簡単に言うと必要なタイミングで不要なデータをメモリから解放するものです。
人間が不要な記憶を消すようなもので、ここで重要なのは不要と判断されるタイミングです

let A = 1;
A = 2;  //変数Aに2が代入されたことにより1が解放される。
console.log(A); //2

これは関数でも起きます。解放されるのが先程の変数を中に入れたループ関数です。
ここで思うのは関数が終わったタイミング変数のデータは解放されると思いますが違っていて
次に解放されないパターンです

function A() {
  let a = 0;
  return a;
};

const B = A();
console.log(B); //0

やってることはリターンで返して変数に入れてるだけです。( )は関数の実行をします。
const B = A( );としているので関数自体は実行されてますが結果としてはコンソールに0と表示されます。
実際にデータが解放されるのはどこからも参照されなくなったときに解放されます。
この場合関数が終了してもconst Bに参照されてるため消えません。

静的スコープとはなんですか?

一言でいえば変数の参照は変わらないってだけです。
javascriptは静的スコープですが他言語では動的スコープもあるらしいです

const a = 1;

function A() {
    console.log(a);
}

function B() {
    const a = 2;
    A(); 
}

B(); //1

loa(a)は最初に上の1を参照します。その後別の関数に値の変わった変数があるのに結果は1が出る

クロージャー

片やデータの解放、片や参照元が変わらない。それで何が出来るんじゃいという話。クロージャーになります。
これも簡単にいうと関数にデータ保持させたろってことです。

function A() {
  let count = 0;

  function B() {
    count += 1;
    return count;
  }
  return B;
}

const C = A();
console.log(C()); //1
console.log(C()); //2
console.log(C()); //3
console.log(C()); //4
console.log(C()); //5

まぁこれだけ見るとショボって思うでしょう。私も思います。
グローバル変数が減るのと関数に状態を持たれるのがメリットとのことです。
試しに作ったけど、うん。何がすごいかわからない。入力値が5に対しての関数です。

function A(a) {
  return function B(b) {
    if(a > b){
      console.log(a + "の方が大きい!");
    } else if (a < b) {
      console.log(a + "より小さい!");
    } else {
      console.log("値が同じ!");
    }
  }
}

const A5 = A(5);
A5(2); //5の方が大きい!
A5(4); //5の方が大きい!
A5(6); //5より小さい!
A5(8); //5より小さい!
A5(5); //値が同じ!

おわり

軽い気持ちで調べたらえらくかかりました。クロージャーの凄さは分からなかったですがいつか使うでしょう。
何か個人的に画期的にものが思いついたらまた書きます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0