JavaScriptにおけるスコープとクローズドの問題について話します.

1728 ワード

JavaScriptのスコープは関数を境界とし、異なる関数は相対的に独立したスコープを有する.関数の内部では大域変数を宣言してアクセスすることができます.また、局所変数(varキーワードを使用して、関数のパラメータも局所変数です.)を宣言することもできますが、関数の外部では内部の局所変数にアクセスできません.

function test() {
var a = 0; //     
b = 1; //     
}
a = ?, b = ? // a undefined,b 1
同じ名前の局所変数は大域変数をカバーしますが、本質的には2つの独立した変数です.一方が変化しても他方に影響はありません.

a = 5; //    a   5
function test() {
var a = 4; //    a   4
}();
a = ? //    a    5,      
一般的には、関数が終了すると、関数内部変数への参照はすべて終了し、関数内の局所変数は回収され、関数の実行環境はクリアされますが、内部関数を関数として返した場合には、変化が発生します.

function test(i) {
var b = i * i;
return function() {
return b--;
};
}
var a = test(8);
a(); //     64,     b 63
a(); //     63,     b 62
内部関数を返却値とすると、関数終了後の内部変数の参照が終了していないため、関数のローカル変数が回収できず、関数の実行環境が保留されているため、クローズド効果が形成され、この参照により回収された内部変数にアクセスすることができます.クローズドはまた、関数の局所変数を「プライベート」変数として使用し、戻り内部関数のみでアクセスでき、他のいかなる手段でも変更できない.したがって、ローカル変数および保護変数を維持するために、クローズドパケットを使用することができる.クローズドを使用しない場合:

var a = []; //   a   5   
for (var i = 0, m = a.length; i < m; i++) {
a[i].onclick = function(e) {
return 'No. ' + i;
};
}
//         ,     “No. 5”,  i     5
       :
function test(i) {
return function(e) {
return 'No. ' + i;
};
}
var a = []; //   a   5   
for (var i = 0, m = a.length; i < m; i++) {
a[i].onclick = test(i);
}
//           ,      No. 0 ~ No. 4
クローズドは便利さをもたらすと同时に、いくつかの弊害をもたらします.1、プログラムの复雑さが増加し、より困难なことを理解します.2、正常なゴミの回収を妨害します.复雑なクローズドはメモリが回収できなくて、崩壊する可能性があります.クローズドの出現自体は言語のバグですが、ユニークな機能のために保存されています.それは主要な機能ではなく補助手段です.