LoginSignup
1
0

More than 1 year has passed since last update.

javaScript クロージャーってナンジャ

Last updated at Posted at 2022-04-19

javaScriptのクロージャーでちょっと詰まった話

javaScriptの学習を進めていくと、一度クロージャの壁にぶち当たる。

クロージャーに入る前に、まずは変数のスコープについておさらいしてみる。

qiita.js
function test(val) {
  return val;
}

console.log(test('テスト')) // テスト

console.log(val); // エラー Uncaught ReferenceError: val is not defined at...

上記コードのように、関数内で定義された変数 val を関数外で取得しようとしても、エラーになり、これにはスコープが影響している。

スコープにはいくつか種類があり、それぞれ参照範囲が異なる。
詳しくはこちらの記事を参考にしてほしい。

Javascript のクロージャについて

おねがい
上記の記事で満足してしまうかもしれないが、この記事に戻ってきてほしい

スコープの種類とクロージャーの概要について理解できたところで、ここからが本題。
私が詰まったところの説明をする。

qiita.js
const counterGenerator = (val) => {
  let i = val;
  return () => i += 1;
}

const test = counterGenerator(0);
test(); // 1
test(); // 2
test(); // 3
test(); // 4

上記コードを理解いただけただろうか。
関数test() を実行するたびに、返される値が変化(今回はカウントアップ)していくのである。
私は、初めこれにかなりの違和感を感じた。
同じく違和感を感じた初心者諸君、これから一緒にコード内容を紐解いていこう。

注意
ここからは誤った解釈があるかもしれない。先に謝っておく。
(コメントで教えて下さい)

まずはクロージャー部分

qiita.js
const counterGenerator = (val) => {
  let i = val;
  return () => i += 1;
}

関数 counterGenerator は、数値型の引数を一つとり、返り値として関数を返す。

この関数 counterGenerator に引数0を渡して呼び出し、返り値 test を変数に入れてみる。

qiita.js
const test = counterGenerator(0);

これで、変数 test には関数が代入された。
この test に、呼び出し演算子 () をつけて関数の呼び出しができる。

qiita.js
test(); // 1
test(); // 2
test(); // 3
test(); // 4

この部分だ。何度みても違和感しかない。

関数 test() を実行するたびに、関数内の変数 i がカウントアップされ、その値が返されてくる。
今回はそういう関数を、関数 counterGeneratorn 内で定義した。

この変数 i をプライベート変数といい、外部から直接操作したり、取得することができない。

その名の通りプライベートな変数だ。

test() だとぱっと見、なんの関数を実行しているのかわからないため、改めて定義する関数名を気をつけないといけないと感じた。
例えば、countUp() とか。

javaScriptの奥は深い。また詰まったことがあったら投稿する。以上。

1
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
1
0