2011-02-02 8 views
1

私は次のコードを持っている:Javascriptの無名関数

for (var i=0; i < 20; i++) { 
    var itemButton = $('<button />').click(function(){ alert('Hello'); }).append('Hello'); 
    $('#container').append(itemButton);        
} 

私はonclickの機能をそれぞれのボタンの多くを作成します。それから私は$('#shopSearchTopBar').empty();を使用して#コンテナをクリアし、ボタンをもう一度作成します。

私の質問です:これはメモリリークの可能性がありますか? Javascriptは、#container上で.empty()メソッドを呼び出すか、メモリが解放されたときに初めて作成した匿名関数に使用されるメモリを解放しますか?自分の新しい匿名関数を持つ20個の新しいボタンを安全に追加できますか?

+0

click()の代わりにbind()を使用します。提示する方法ではなくqndを使用します。 – yoda

+1

@yoda:ハンドラーを割り当てるための 'bind'と' click'の間に機能的な違いはありません。 – user113716

+0

@patrick dw:そこにチェックしてください:http://api.jquery.com/bind/あなたはコードを短くすることができます。また、マークアップが頻繁に変更される場合は、live()をお勧めします。 – yoda

答えて

4

これらの機能は、jQuery.cacheに格納されています。

.empty()のようなjQueryメソッドを使用する限り、そのデータは影響を受けるすべての要素に対してクリーンアップされます。

あなたはこのような何かをした場合:

その後
document.getElementById('container').innerHTML = ''; 

各要素とjQuery.cacheとの間の接続が切断されるので、あなたは、おそらくかなり厄介なメモリリークを持っていると思いますし、データが(そしておそらくそれ以上)になるとキャッシュに孤立している。

コンテンツを削除/上書きするときにjQueryメソッドに固執すると、問題ありません。これをやったとしても

$('#container').html(''); 

... jQueryの影響を受けた要素のためにそのデータをクリーンアップします。

+0

@patrick dw:html()は、私がテストした限り、DOMをクリアしません。 – yoda

+0

@yoda:そうです。 http://jsfiddle.net/cPRqw/あなたは私の答えにしたように空の引用符を渡す必要があります。 – user113716

+0

@patrick dw:これはマークアップであり、DOMではありません。とにかく、私はその問題を横断してからしばらくしていますが、それが解決されたかどうかは分かりません。 – yoda

0

すべての匿名関数が警告を表示する場合は、ループ外に関数を定義し、名前で参照します。そうすれば、20回ではなく1回だけ作成されます。

var clickHandler = function(){ alert('Hello'); }; 

for (var i=0; i < 20; i++) { 
    var itemButton = $('<button />').click(clickHandler).append('Hello'); 
    $('#container').append(itemButton);                             
} 

ここではクロージャを使用すると異なりますが、そうは思われません。

+0

私はalert()を使って私の例を単純にしました。これらの関数はもっと多くのことを行い、また$(this)を使用するので、私はあなたが示唆したようにループ外の関数を使うことはできないと思います。 – daniels

+0

はい、そうです。私はメモリリークの側面にもっと焦点を当てていました。効率の面では、ループ内で同一の関数を構築すべきではありません。名前付き関数を作成すると、単一のインスタンスを共有できます。 – user113716

+2

@ダニエルズ:そういうのは大丈夫です。 'this'は、関数が呼び出されたときに割り当てられます。最終的に、この '$( '。someElements')click(function(){})'のようないくつかの要素にハンドラを割り当てると、jQueryは異なる要素間の関数への共有参照を使用して効果的に同じことをします。 – user113716