0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

クロージャーを理解する

Last updated at Posted at 2021-12-19

クロージャーの定義

クロージャは、組み合わされた(囲まれた)関数と、その周囲の状態(レキシカル環境)への参照の組み合わせです。言い換えれば、クロージャは内側の関数から外側の関数スコープへのアクセスを提供します。JavaScript では、関数が作成されるたびにクロージャが作成されます。by_MDN

意味がわかりません。順を追ってみていきましょう。

クロージャーを理解するために理解するべきこと4つ

1: JavaScriptは関数の中に関数を定義できる
```javascript function hello() { function child() { console.log("helloの子供だよ") } return child; }

console.log(hello());

//コンソール
ƒ child() {
console.log("helloの子供だよ")
}


hello()を実行すると戻り値として、child関数を返しているため、コンソールのような結果になります。

普段JavaScriptを書いている方であれば、普通にやっていることですよね。

<h5>2: JavaScriptの関数は変数として持ち運べる</h5>

```javascript
const x = hello()
console.log(x)

//コンソール
ƒ child() {
    console.log("helloの子供だよ")
  }

先ほど実行したhello()関数をそのまま変数に入れてしまうことができます。

もちろんコンソールは変数に入れただけですので、同じ結果になります。

この変数xに入った関数を実行すると

x()

//コンソール
helloの子供だよ

といった具合になります。

そして、変数としても運べるということは、引数として利用することもできます。

引数を一つ受け取る関数を用意し、変数に格納された関数を渡してみます。

function receive(v) {
  console.log("引数で受け取ったvを実行するよ")
  v();
}

receive(x)

//コンソール
引数で受け取ったvを実行するよ
helloの子供だよ

ここまでがJavaScriptの関数は変数として持ち運べるの説明になります。

3:JavaScriptの関数は親の関数の変数を扱える

前提として一方の関数からほかの関数の変数を使うことはできません

function suda() {
  const masaki = "菅田将暉"
}

function komatsu() {
  console.log(masaki)
}

komatsu();

//コンソール
エラー

しかし関数が親子関係にある場合、子供の関数は、親の変数を使うことができます。
この場合、親がsuda()で子供がkomatsu()になります。(本当は夫婦なんですけどね)

※親が子供の変数を使うことはできません

function suda() {
  const masaki = "菅田将暉"
  function komatsu() {
    const nana = "小松奈菜"
    console.log(masaki)
    console.log(nana)
  }
  komatsu()
}

suda()

//コンソール
菅田将暉
小松奈菜
4:JavaScriptの関数の親は生みの親のことである

言葉の定義

・ダイナミックスコープ
関数を実行するときの親を親とする

・レキシカルスコープ
自分を定義した関数を親とする

関数の親の決め方には、上記の二種類があって、JavaScriptはレキシカルスコープを採用している。

例えば、このような親子関係の関数があります。

function suda() {
  const masaki = "菅田将暉"
  function komatsu() {
    const nana = "小松奈菜"
    console.log(masaki)
    console.log(nana)
  }
  return komatsu
}

komatsu()関数の親はsuda()関数です。

次にsuda()関数を実行し、戻り値であるkomatsu()関数を変数suda_returnに格納します


function receive(v) {
  const masaki = "相葉雅紀"
  v();
}

const suda_return = suda()

receive(suda_return )

//コンソール
菅田将暉
小松奈菜

レキシカルスコープの定義を見ると「自分を定義した関数を親とする」とあります。

receive()関数の引数v()関数の中身を見ると


function receive(v) {
  const masaki = "相葉雅紀"
  function komatsu() {
    const nana = "小松奈菜"
    console.log(masaki)
    console.log(nana)
  }
  komatus()
}

となっており変数masakiには相葉雅紀が入りそうですが、これは自分を定義した関数ではありません。

従って、コンソールにはkomatus()関数を定義した親にあったmasakiの変数に入っていた菅田将暉が現れるわけです。

そして、初めの意味わからなかったクロージャを簡単にした説明は、

「関数と生みの親(祖先含め全員)が持っている変数を合わせてクロージャと呼ぶ」

----------追記予定----------

具体的なクロージャーの使いかた

0
1
1

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?