JS閉鎖
閉鎖前に知っておくべきこと
1。関数範囲
(1)。 JS言語の特別な機能は、グローバル変数を関数内で直接読み取ることができることです
コードコピーは次のとおりです。
<script type = "text/javascript">
var n = 100;
function parent(){
アラート(n);
}
親(); // 100
</script>
PHPの場合
コードコピーは次のとおりです。
<?php
$ n = 100;
function parent(){
エコー$ n;
}
親(); //エラーが報告されますnは定義されていません
?>
(2)。関数内のローカル変数は、関数の外側で読み取ることができません
コードコピーは次のとおりです。
<script type = "text/javascript">
function parent(){
var m = 50;
}
親();
アラート(m); //エラーmは定義されていません
</script>
変数を内部で宣言する場合、VARを追加する必要があります。そうしないと、グローバル変数が宣言されることに注意してください。
コードコピーは次のとおりです。
function parent(){
m = 50;
}
親();
アラート(m); // 50
//もちろん、これはPHPでさらにそうです。
コードコピーは次のとおりです。
<?php
function parent(){
グローバル$ m; //グローバル、定義、および割り当てを分離する必要があります
$ m = 50;
}
親();
エコー$ m; // 50
?>
//グローバルがない場合、定義エラーはありません
関数内のローカル変数を取得する必要がある場合、JS変数の範囲の特性を使用する必要がある場合があります。たとえば、子どもの関数を定義し、子の機能については、親関数はそのグローバルであり、子関数は親関数の変数にアクセスできます(JSコード全体では、ローカル変数です)
コードコピーは次のとおりです。
<script type = "text/javascript">
function parent(){
var m = 50;
functionson(){
アラート(M);
}
息子を返します。
}
var s = parent(); //結果をグローバルに保存します
s(); // 50
</script>
親の中のすべての局所変数は子供の機能に表示されますが、子の機能内のローカル変数は親機能には見えません。これは、JSに固有のチェーンスコープ構造です。子オブジェクトは、すべての親オブジェクトの変数レベルごとに検索されます。親オブジェクトのすべての変数は、子オブジェクトに表示されます。上記の息子機能は閉鎖です
一部の学生はこれを行うかもしれません
コードコピーは次のとおりです。
function parent(){
var m = 50;
functionson(){
アラート(M);
}
}
親();
son()//関数sonは定義されていません
JavaScriptでは、関数で宣言された関数はローカルであり、関数が実行された後にリリースされることに注意してください。
これとPHPの違いに注意してください
コードコピーは次のとおりです。
<?php
function parent(){
functionson(){
$ m = 50;
エコー$ m;
}
}
親();
son(); //出力50はエラーを報告しません
?>
閉鎖
関数関数を内部的に定義し、内部および外部関数を接続するブリッジ
閉鎖には2つの機能があります。
まず、前述の変数内の読み取り関数、
2つ目は、これらの変数の値をメモリ内に保存して、データ共有を実現することです
閉鎖の例をいくつか紹介します
コードコピーは次のとおりです。
<script type = "text/javascript">
var cnt =(function(){
var i = 0;
return function(){
アラート(i);
i ++;
}
})();
cnt(); // 0
cnt(); // 1
cnt(); // 2
cnt(); // 3
</script>
メモリ内の匿名関数の実行結果(つまり、サブ機能の宣言をグローバル変数カットに割り当てる)を保存します
Cut()を実行すると、値はメモリから直接取得されます。 CNT()関数のみを呼び出すことができ、直接警告することはできません(i)
パラメーターを閉鎖に転送することもできます
コードコピーは次のとおりです。
var cnt =(function(num){
return function(){
アラート(num);
num ++;
}
})(5);
cnt(); // 5
cnt(); // 6
cnt(); // 7
//もちろん、呼び出し時にパラメーターを渡すこともできます
var cnt =(function(){
var i = 0;
return function(num){
num+= i;
アラート(num);
i ++;
}
})();
CNT(1); // 1
CNT(2); // 3
CNT(3); // 5
閉鎖をよりよく理解するために、次のコードを見ていきます
たとえば、アレイに5つの関数を持つ配列を返し、最初の関数が0、2番目の関数がポップアップします1 ...
コードがこのように書かれている場合
コードコピーは次のとおりです。
functionbox(){
var arr = [];
for(i = 0; i <5; i ++){
arr = function(){return i;}
}
arrを返します。
}
var a = box();
アラート(a); // 5つの関数本体を含む配列
アラート(a [0]());
アラート(a [1]());
ポップアップ関数本文
function(){return i;}}
最後に、これは4です、そして++は5になります
ループ停止用
すべてがポップアップしたことがわかったが、これは明らかに私たちの要件を満たしていなかった
解決策1
内部の関数の自己解明
コードコピーは次のとおりです。
functionbox(){
var arr = [];
for(i = 0; i <5; i ++){
arr =(function(num){return i;})(i);
}
arrを返します。
}
var a = box();
for(var i = 0; i <a.length; i ++){
アラート(a);
}
しかし、返された配列の要素は関数の実行の結果であることがわかりましたが、私たちが望むのは、関数をアップグレードする必要があることです。
解決策2
閉鎖の実装
コードコピーは次のとおりです。
functionbox(){
var arr = [];
for(var i = 0; i <5; i ++){
arr =(function(num){
return function(){return num;}
})(私);
}
arrを返します。
}
var arr = box();
for(var i = 0; i <5; i ++){
alert(arr()); // 0,1,2,3,4
}
キーコード
コードコピーは次のとおりです。
arr =(function(num){
return function(){return num;}
})(私);
i = 0の場合
arr [0] =(function(num){return function(){return num;}})(0);
1時
arr [1] =(function(num){return function(){return num;}})(1);
上記は閉鎖の利点です!非常にシンプルで実用的です。