クロージャー (Closure) とは、関数 (内部関数とも呼ばれます) がその外部関数の変数にアクセスできることを意味し、外部関数の実行が完了した後でも内部関数はアクセスできます。外部関数の変数に引き続きアクセスして操作できます。クロージャは、プライベート変数を作成し、カリー化などの関数を実装するためにプログラミングでよく使用されます。
ただし、クロージャを誤って使用すると、メモリ リークが発生する可能性があります。つまり、メモリ内のオブジェクトが正常に解放されず、過剰なメモリ消費が発生する可能性があります。
以下は、クロージャによって引き起こされる一般的なメモリ リークと特定のコード例です:
function addListeners() { var elements = document.getElementsByTagName('button'); for (var i = 0; i < elements.length; i++) { elements[i].addEventListener('click', function() { console.log('Button ' + i + ' clicked'); }); } }
Above コード内では、ループ関数内のイベント処理関数は外部ループ変数 i
を使用します。JavaScript のクロージャ機構により、各イベント処理関数は同じ i
変数を参照します。ボタンがクリックされたときの場合、イベント ハンドラー関数の i
変数は、ループの終了時点ですでに最終値になっています。したがって、どのボタンがクリックされても、コンソール出力結果は ボタン 3 がクリックされました
となります。これにより、イベント ハンドラーが i
への参照を保持したままになり、ループ終了後に変数がガベージ コレクションされなくなるため、メモリ リークが発生しました。
解決策:
function addListeners() { var elements = document.getElementsByTagName('button'); for (var i = 0; i < elements.length; i++) { (function(index) { // 使用立即执行函数创建一个新的作用域 elements[index].addEventListener('click', function() { console.log('Button ' + index + ' clicked'); }); })(i); } }
function startTimer() { var count = 0; var timer = setInterval(function() { count++; console.log(count); if (count >= 5) { clearInterval(timer); } }, 1000); }
上記のコードでは、タイマーは 1 秒ごとに匿名関数を実行します。はい、匿名関数が外部関数 startTimer
の count
変数を参照しているため、count
がガベージ コレクションに失敗し、メモリ リークが発生します。
解決策:
function startTimer() { var count = 0; var timer = setInterval(function() { count++; console.log(count); if (count >= 5) { clearInterval(timer); timer = null; // 清除对定时器的引用 } }, 1000); }
function createClosure() { var data = new Array(1000000).join('*'); // 创建一个大字符串对象 return function() { console.log(data); }; }
上記のコードでは、createClosure
関数はクロージャ関数では、クロージャ関数は外部関数の data
変数を参照します。data
は大きな文字列オブジェクトであるため、クロージャ関数は常に data## への参照を保持します。 # の結果、
data がガベージ コレクションできなくなり、メモリ リークが発生します。
function createClosure() { var data = new Array(1000000).join('*'); // 创建一个大字符串对象 return function() { console.log(data); data = null; // 清除对data的引用 }; }
以上がクロージャによるメモリ リークはどのような状況で発生する可能性がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。