JavaScript 閉包

JavaScriptの変数は属しています本地グローバルローカル

またはクロージャスコープ。

を通じてローカル(プライベート)を実現できます。

グローバル変数関数は関数をアクセスできます。内部

インスタンス

function myFunction() {
    var a = 4;
    return a * a;
} 

実際に試してみましょう

関数は関数も定義したすべての変数にアクセスできます。外部定義された変数、例えば:

インスタンス

var a = 4;
function myFunction() {
    return a * a;
} 

実際に試してみましょう

最後の例では、aグローバル変数。

ウェブページでは、グローバル変数はwindowオブジェクトに属しています。

グローバル変数はページ中(およびウィンドウ中)のすべてのスクリプトで使用および変更できます。

最初の例では、aローカル変数。

ローカル変数はその定義された関数内だけで使用できます。他の関数やスクリプトコードには見えません。

同じ名前のグローバル変数とローカル変数は異なる変数です。一方を変更しても他方には影響しません。

を通じてキーワード var 作成された変数は常にグローバルです、即ち、それが関数内で作成された場合でもです。

変数のライフサイクル

グローバル変数はあなたのアプリケーション(ウィンドウ、ウェブページ)と同じ長さで生き続けます。

ローカル変数は長く生きません。それらは関数呼び出し時に作成され、関数が終了すると削除されます。

カウンタのジレンマ

変数を使用してカウンタを数え、このカウンタがすべての関数で使用できるようにしたい場合

グローバル変数と関数を使用してカウンタを増加させることができます:

インスタンス

// カウンタを初期化します
var counter = 0;
// カウンタを増加させる関数
function add() {
  counter += 1;
}
// add()を3回呼び出します
add();
add();
add();
// この時カウンタは3であるべきですが

実際に試してみましょう

この解決策には問題があります:ページ上のどんなコードでもカウンタを変更できますが、add()を呼び出す必要はありません。

add()関数に対して、カウンタはローカルでなければならず、他のコードがそれを変更しないようにします:

インスタンス

// カウンタを初期化します
var counter = 0;
// カウンタを増加させる関数
function add() {
  var counter = 0; 
  counter += 1;
}
// add()を3回呼び出します
add();
add();
add();
// この時カウンタは3であるべきですが、0です。

実際に試してみましょう

使いません。なぜなら、グローバルカウンタではなくローカルカウンタを表示するからです。

関数が自分自身を返すことを通じて、グローバルカウンタを削除しローカルカウンタにアクセスできます:

インスタンス

// カウンタを増加させる関数
function add() {
  var counter = 0; 
  counter += 1;
  return counter;
}
// add()を3回呼び出します
add();
add();
add();
// この時カウンタは3であるべきですが、1です。

実際に試してみましょう

使いません。なぜなら、関数を呼び出すたびにローカルカウンタがリセットされるからです。

JavaScriptの内部関数がこの問題を解決できます。

JavaScriptのネスト関数

すべての関数はグローバルスコープにアクセスする権利があります。

実際には、JavaScriptではすべての関数は「上層」のスコープにアクセスする権利があります。

JavaScriptはネスト関数をサポートしており、ネスト関数は上層のスコープにアクセスできます。

この例では、内部関数 plus() 親関数内でアクセスできます。 counter 計数器変数:

インスタンス

function add() {
    var counter = 0;
    function plus() {counter += 1;}
    plus();     
    return counter; 
}

実際に試してみましょう

カウンタの困難を解決するために、カウンタを外からアクセスできる場合は、これで十分です。 plus() 関数を見つける必要があります。

私たちは一度だけ実行される counter = 0 の方法で

私たちにはクロージャが必要です(closure)。

JavaScript 閉包

自己呼び出し関数を覚えていますか?この関数は何をしますか?

インスタンス

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
add();
add();
add();
// カウンタは現在 3 です 

実際に試してみましょう

例説明

変数 add の代入は自己呼び出し関数の返値です。

この自己呼び出し関数は一度だけ実行されます。カウンタを 0 に設定し、関数式を返します。

このように、add が関数になります。最も「面白い」部分は、それが親作用域のカウンタにアクセスできることです。

これは JavaScript クロージャ。これにより、関数には「プライベート「変数」が可能になります。

カウンタはこの匿名関数のスコープによって保護されており、add 関数を使用してのみ変更できます。

クロージャとは、親作用域にアクセス権を持つ関数であり、親関数が閉じた後にでもアクセスできる関数のことです。