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 = 4;
function myFunction() {
	document.getElementById("demo").innerHTML = a * a;
} 
</script>

</body>
</html>

インスタンスの実行»

オンラインインスタンスを表示するには、[インスタンスの実行]ボタンをクリックしてください

後者のインスタンスでは、aグローバル変数。

Web ページのグローバル変数は window オブジェクトに属します。

グローバル変数は、ページ上のすべてのスクリプトに適用されます。

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

ローカル変数は、それが定義されている関数内でのみ使用できます。他の関数またはスクリプト コードでは使用できません。

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

Note変数宣言は、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() 関数が呼び出されていなくても、ページ上のどのスクリプトでもカウンターを変更できるのです。

関数内でカウンターを宣言した場合、関数を呼び出さずにカウンターの値を変更することはできません:

インスタンス

<!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() は親関数の counter 変数にアクセスできます:

Instance

<!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>

Run Instance»

[Run Instance] ボタンをクリックして表示します。オンライン インスタンス

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 メソッドを通じてのみ変更できます。

Noteクロージャとは、上位関数がクローズされている場合でも、上位関数のスコープ内の変数にアクセスできる関数です。