JavaScript クロージャ
JavaScript 変数はローカル変数またはグローバル変数にすることができます。
プライベート変数はクロージャを使用できます。
グローバル変数
この関数は、次のような関数内で定義された変数にアクセスできます:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <p>访问函数内部定义的变量:</p> <button type="button" onclick="myFunction()">查看</button> <p id="demo"></p> <script> function myFunction() { var a = 4; document.getElementById("demo").innerHTML = a * a; } </script> </body> </html>
プログラムを実行して試してみましょう
この関数は、次のような関数の外部で定義された変数にもアクセスできます:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <p>函数可以访问定义在函数外的变量:</p> <button type="button" onclick="myFunction()">点我</button> <p id="demo"></p> <script> var a = 5; function myFunction() { document.getElementById("demo").innerHTML = a * a; } </script> </body> </html>
プログラムを実行してみよう
次の例では、 a はグローバル変数です。
Web ページのグローバル変数は window オブジェクトに属します。
グローバル変数は、ページ上のすべてのスクリプトに適用されます。
最初の例では、a はローカル変数です。
ローカル変数は、それが定義されている関数内でのみ使用できます。他の関数またはスクリプト コードでは使用できません。
グローバル変数とローカル変数は、同じ名前であっても、2 つの異なる変数です。どちらかの値を変更しても、もう一方の値には影響しません。
ヒント: 変数が var キーワードを使用せずに宣言されている場合、それが関数内で定義されている場合でも、それはグローバル変数です。
変数のライフサイクル
グローバル変数のスコープはグローバルです。つまり、グローバル変数は JavaScript プログラム全体のあらゆる場所にあります。
関数内で宣言された変数は関数内でのみ機能します。これらの変数はローカル変数であり、そのスコープはローカルです。関数のパラメータもローカルであり、関数内でのみ機能します。
カウンターのジレンマ
いくつかの値を数えたい場合、カウンターはすべての関数で使用できると想像してください。
グローバル変数と関数を使用してカウンターの増分を設定できます:
例
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <p>全局变量计数。</p> <button type="button" onclick="myFunction()">计数!</button> <p id="demo">0</p> <script> var counter = 0; function add() { return counter += 1; } function myFunction(){ document.getElementById("demo").innerHTML = add(); } </script> </body> </html>
プログラムを実行して試してください
add() 関数が実行されるとカウンター値が変化します。
しかし、ここで問題が発生します。add() 関数が呼び出されていなくても、ページ上の任意のスクリプトでカウンターが変更される可能性があります。
関数内でカウンターを宣言した場合、関数を呼び出さずにカウンターの値を変更することはできません:
Instance
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <p>局部变量计数。</p> <button type="button" onclick="myFunction()">计数!</button> <p id="demo">0</p> <script> function add() { var counter = 0; return counter += 1; } function myFunction(){ document.getElementById("demo").innerHTML = add(); } </script> </body> </html>
プログラムを実行して試してください
上記のコードは出力されません正しくは、add() 関数を呼び出すたびに、カウンターは 1 に設定されます。
JavaScript の組み込み関数でこの問題を解決できます。
JavaScript 組み込み関数
すべての関数はグローバル変数にアクセスできます。
実際、JavaScript では、すべての関数がその上のスコープにアクセスできます。
JavaScript はネストされた関数をサポートしています。ネストされた関数は、上位レベルの関数変数にアクセスできます。
この例では、埋め込み関数 plus() は親関数のカウンター変数にアクセスできます:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <p>局部变量计数。</p> <p id="demo">0</p> <script> document.getElementById("demo").innerHTML = add(); function add() { var counter = 0; function plus() {counter += 1;} plus(); return counter; } </script> </body> </html
プログラムを実行して試してください
plus() 関数に外部からアクセスできれば、これで問題を解決できますカウンタージレンマ。
counter = 0 が 1 回だけ実行されるようにする必要もあります。
閉鎖が必要です。
JavaScript クロージャ
関数自体を呼び出していることを覚えていますか?この機能は何をするのでしょうか?
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <p>局部变量计数。</p> <button type="button" onclick="myFunction()">计数!</button> <p id="demo">0</p> <script> var add = (function () { var counter = 0; return function () {return counter += 1;} })(); function myFunction(){ document.getElementById("demo").innerHTML = add(); } </script> </body> </html>
プログラムを実行して試してみましょう
分析例
変数addは関数の自己呼び出しの戻り値を指定します。
自己呼び出し関数は 1 回だけ実行されます。カウンタを 0 に設定します。そして関数式を返します。
add変数は関数として使用できます。優れた点は、関数の上のスコープからカウンターにアクセスできることです。
これは JavaScript クロージャと呼ばれます。これにより、関数がプライベート変数を持つことが可能になります。
カウンターは匿名関数のスコープによって保護されており、add メソッドを通じてのみ変更できます。
ヒント: クロージャは、前の関数が閉じられている場合でも、前の関数のスコープ内の変数にアクセスできる関数です。