Skip to content
Skip to content
Menu
Info Cafe
Info Cafe

A simple guide to understand closures in JavaScript

By admin on 1月 20, 2021

JavaScriptにおけるクロージャは、多くの人が理解に苦しむ概念の1つです。 以下の記事では、クロージャとは何かをわかりやすく説明し、簡単なコード例を使ってポイントを押さえていきます。

クロージャとは、内側の関数が外側(囲んでいる)の関数の変数にアクセスできる、JavaScriptの機能の1つで、スコープチェーンのことです。

クロージャには 3 つのスコープ チェーンがあります:

  • 自分自身のスコープ (中括弧の間に定義された変数) にアクセスできます
  • 外側の関数の変数にアクセスできます
  • グローバル変数にアクセスできます

この定義は、慣れていない人にとっては、ただのたくさんの専門用語のように思えるかもしれません!

でも、実際にクロージャとは何でしょうか?

JavaScriptで簡単なクロージャの例を見てみましょう

function outer() { var b = 10;
function inner() {
var a = 20;
console.log(a+b);
}
return inner;
}

ここに2つの関数があります。

  • 外側の関数outerbbinner 関数を返す
  • 変数をainnerouterbを、その関数本体内でアクセスしています

変数bouterainner 関数に限定されます。

ここで、outer()outer()Xouter()Yに格納してみましょう。

では、outer()の関数が最初に呼び出されたときに何が起こるかを順を追って見ていきましょう。

  1. 変数 bouter()10 に設定されます。
  2. 次の行は関数宣言なので、実行するものはありません。
  3. 最後の行では、return innerinnerinnerinnerを返します。
  4. return文で返された内容は、Xに格納されます。
    つまり、Xには次のように格納されます:
    function inner() {
    var a=20;
    console.log(a+b);
    }
  5. 関数 outer()outer() のスコープ内のすべての変数はもはや存在しません。

この最後の部分を理解することが重要です。

関数の中で定義された変数の寿命は、その関数の実行の寿命です。

つまり、console.log(a+b)bouter()という関数が実行されている間だけ存在するということになります。

2回目の実行時には、関数の変数が再び作成され、関数の実行が完了するまでの間だけ存在することになります。

このように、outer()が2回目に起動されたときは、以下のようになります。

  1. 新しい変数 bouter()10 に設定されます。
  2. 次の行は関数の宣言なので、何も実行しません。
  3. return innerinnerに返します。
  4. return文で返された内容はYに格納されます。
  5. 関数 outer()outer() のスコープ内のすべての変数が存在しなくなりました。

ここで重要なのは、outer()bouter()bは再び存在しなくなります。

ここが最も重要なポイントです。

これが最も重要な点です。関数内の変数は、関数が実行されているときにのみ存在し、関数の実行が完了すると存在しなくなります。

さて、コード例に戻って、XYouter()XYは関数です。

このことは、JavaScriptのコードに以下を追加することで簡単に確認できます。

console.log(typeof(X)); //X is of type function
console.log(typeof(Y)); //Y is of type function

変数 XY が関数であることから、実行することができます。 JavaScriptでは、X()Y()()を付けることで、関数を実行することができます。

X()Y()inner 関数を実行していることになります。

ここでは、X()が初めて実行されたときに何が起こるかを順を追って見ていきましょう。

  • 今度はJavaScriptがa + bを実行しようとします。 ここで面白いことが起こります。 JavaScriptはaa + bbbbouter()outer()X()outerbも存在しなくなります。
  • JavaScriptではどのように処理しているのでしょうか?

    クロージャ

    JavaScriptのクロージャにより、innerinner関数は、囲み関数が実行された時点での囲み関数のスコープチェーンを保持しているため、囲み関数の変数にアクセスすることができるのです。

    この例では、innerouter()b=10の値を保存しており、引き続き保存(閉鎖)しています。

    ここでスコープ チェーンを参照すると、変数 b の値をスコープ チェーン内に持っていることに気づきます。

    従って、JavaScriptはa=20b=10a+bを計算することができます。

    上記の例に次のコード行を追加することで検証できます。

    Google ChromeでInspect要素を開き、Consoleに移動します。 要素を展開して、実際にClosureb=10Closureouter()の中に保持されていることに注目してください。

    変数b=10はクロージャーに保存されています。 Closures in Javascript

    ここで、最初に見たクロージャの定義を再確認し、より意味のあるものになったかどうかを見てみましょう。

    では、内側の関数は3つのスコープ チェーンを持っています。

    • 自身のスコープへのアクセス – 変数 a
    • outerb,
    • 定義されている可能性のあるグローバル変数へのアクセス

    クロージャの動作

    クロージャのポイントを強調するために、3 行のコードを追加して例を拡張してみましょう。

    このコードを実行すると、console.logに次のような出力が表示されます。

    var X = outer(); // outer() invoked the first time

    関数 outer() が最初に呼び出されます。 以下のような手順で行われます。

    1. 変数 b10
      c が作成されます。
    2. 100
      これを参考までにb(first_time)c(first_time)と呼ぶことにしましょう。
    3. innerX
      binnerb=10innerb を使用しているからです。
    4. outercbinner 内のクロージャとして存在しています。
    var Y= outer(); // outer() invoked the second time
    1. 変数 b10
      c が新たに作成されます。
      outer()bcが存在しなくなっていたにもかかわらず、関数の実行が完了すると、これらは全く新しい変数として作成されることに注意してください。
      これらを参考までに b(second_time)c(second_time) と呼ぶことにします。
    2. innerY
      に代入されています。bはinnerb(second_time)=10innerbを使用しているからです。
    3. outer 関数の実行が完了し、そのすべての変数が消滅します。
      変数 c(second_time)b(second_time)inner 内のクロージャとして存在しています。

    では、次のコード行を実行するとどうなるかを見てみましょう。

    X(); // X() invoked the first time
    X(); // X() invoked the second time
    X(); // X() invoked the third timeY(); // Y() invoked the first time

    X()が初めて起動されたとき、

    1. 変数 a20
    2. a=20bb(first_time)b=10
    3. 変数 ab1 でインクリメントされます。
    4. X()a がすべて消滅します。
      しかし、b(first_time)b(first_time)は存在し続けます。

    X()が2回目に起動されると、

    1. 変数 a が新たに作成されます。
    2. 変数 a20
      X()a の以前の値は存在しません。
    3. a=20
      b(first_time)
      b1b=11
    4. 変数 ab1 だけ増加します。 再び
    5. X()が実行を完了し、その内部変数である変数aがすべて消滅します
      ただし b(first_time)はクロージャが存在し続けるので保存されます。

    X()が3回目に起動されると、

    1. 変数 a が新たに作成されます。
    2. 変数 a20
      X()aの以前の値はもはや存在しません。
    3. a=20bb(first_time)
      また、前回の実行でb1b=12
    4. 変数 abb1が再び
    5. X()a はすべて存在しなくなります
      しかし、b(first_time)はクロージャが存在し続けるので保存されます

    Y()が初めて起動されたとき。

    1. 変数 a20 に設定されます
    2. a=20bb(second_time)b=10
    3. 変数 ab1
    4. Y()aはすべて存在しなくなります
      ただし、b(second_time)b(second_time)は存在し続けます。

    まとめ

    クロージャは、JavaScriptの微妙な概念の1つで、最初は理解するのが難しいものです。

    これらのステップバイステップの説明が、JavaScriptのクロージャの概念を理解するのに役立つことを願っています。

    Other Articles:

    • A quick guide to “self invoking” functions in Javascript
    • Understanding Function scope vs. Block scope in Javascript
    • How to use Promises in JavaScript
    • How to build a simple Sprite animation in JavaScript

    投稿ナビゲーション

    Aric Almirola, Smithfield extend contract with Stewart-Haas Racing
    What is blackface?

    コメントを残す コメントをキャンセル

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

    最近の投稿

    • Firebush (日本語)
    • 9 Best Dog Vitamins And Supplements For Enhanced Health
    • 2021年のCDレート予測。 金利はおそらく低水準で推移するが、年の後半には上昇するかもしれない
    • 慢性骨盤痛症候群と前立腺炎:症状、診断と治療
    • ミックスベリー・クリスプ
    • Low-Carb Chocolate Pudding Recipe
    • 1歳を過ぎた母乳育児のメリット
    • Is it Safe to Dump Coffee Grounds Down the Sink|Atomic Plumbing
    • Cool-Down After Your Workout (日本語)
    • Our Work (日本語)

    メタ情報

    • ログイン
    • 投稿フィード
    • コメントフィード
    • WordPress.org

    アーカイブ

    • 2021年3月
    • 2021年2月
    • 2021年1月
    • 2020年12月
    • DeutschDeutsch
    • NederlandsNederlands
    • EspañolEspañol
    • FrançaisFrançais
    • PortuguêsPortuguês
    • ItalianoItaliano
    • PolskiPolski
    • 日本語日本語
    ©2021 Info Cafe | WordPress Theme by SuperbThemes.com