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. 通常のガベージ コレクションを妨げ、複雑なクロージャーはメモリのリサイクルに失敗してクラッシュする可能性もあります
3. 大規模なクロージャにはパフォーマンスの問題が伴うことがよくあります
したがって、クロージャは大きくて複雑なものではなく、コンパクトでコンパクトである必要があり、クロージャの大規模な使用は避けるべきです。クロージャの出現自体が言語のバグですが、その独自の機能により依然としてバグが残っています。それは補助的な手段であり、主な機能ではありません。