2011-07-14 12 views
30

何か私はJavaScriptの匿名関数はメモリの驚くべき量を使い切ることができると考えています。 )関数にはこの問題はありません。JavaScriptで匿名関数を使用する際に欠点はありますか?例えば。メモリ使用?

私はこれを読んだ場所を覚えていないので、私は戻って再読して自分自身のためにこれを理解することはできません。私は2つの質問持って

  1. は、それが気に価値があるとの匿名関数は十分なメモリを使用できる状況ではありますか? (もしそうなら、例がありますか?)
  2. (名前付き/静的関数ではなく)匿名関数には他にも欠点がありますか?
+0

優秀な質問です。私はその日のために票を使い切った - 他の誰かが私のために+1できる? –

+0

@Michael既にしました。素晴らしい質問。 –

+0

クロージャーの実装*についても同様の質問がありましたが、まだ満足のいく答えで見ています。つまり、現代の* JavaScriptエンジンは、アクセス可能なオブジェクトを囲むだけのスマートなものですか?明らかに、この最適化は 'eval'の存在下で適用するのは現実的ではありません。 –

答えて

7

すべてのJavaScript関数は、スコープチェーン全体の変数環境を継承し、それ自体を含むことで同じように動作します。これは、匿名関数と名前付き関数の両方で同様です。

外部環境への参照の連鎖は、関数が全く異なるスコープに渡されても、各関数にとどまります。

従来は、内部クロージャが存在し続ける限り、任意のチェーン内のすべての変数に参照が保持されていました。コードをコンパイルする現代のブラウザでは、どの変数が実際に参照されているかを分析し、それらの変数のみが保持され、参照されなくなった他のものがガベージコレクションされる可能性があります。

しかし、無名関数が無駄である他の状況があります。

ここでは、コードの共通のビットがあります:

for(var i = 0; i < 100; i++) { 
    (function(j) { 
     setTimeout(function() { console.log(j); }, 1000); 
    })(i); 
} 

これは、ときにあなたがループの中に同一の機能を100回を再現しているので、匿名関数は、もう少し無駄という名前の関数よりもある状況です名前付きのものを再利用することができます。

function setConsole(j) { 
    setTimeout(function() { console.log(j); }, 1000); 
} 

for(var i = 0; i < 100; i++) { 
    setConsole(i); 
} 

これは閉包オーバーヘッドと全く同じですが、新しい変数環境を作成するための関数を1つしか作成していないため、より効率的です。

http://jsperf.com/immediate-vs-named(jsPerfの場合は@Felix Klingありがとうございます。)

特にクロージャに関して、はい、いくつかの永続的な参照によって閉鎖を維持する限り、オーバーヘッドがあります。可能であればこれを避けるのは良いことだが、それに強くはないといいだろう。時には、スコープチェーンに追加された新しい変数環境が単なるベストソリューションです。


EDIT:Here's an article from Google。具体的には、を参照してください。閉鎖を伴う落とし穴の回避。スコープチェーンを拡張することによるパフォーマンスの影響、および名前の付いた関数よりも匿名関数が「遅い」という主張については、

+1

**モデレーター注**この回答の下にある_コメントは、信号よりも多くのノイズに劣化したため、削除されました。コメントは建設的、専門的、そしてとりわけtopic._ –

+1

に残してください。削除のために@Tim Postに感謝します。 OPとの関連ディスカッションの結果と、@ Felix Klingが提供するパフォーマンステストが答えに追加されました。 – user113716

3

IEの閉鎖メモリリークの問題があると思います。

this articleを参照してください。

基本的に、IEの古いバージョンでは、ガベージコレクタはDOMオブジェクトを含む循環参照を処理できませんでした。クロージャはそのような循環参照に非常に役立つので、簡単にIEのメモリリークを引き起こす可能性があります。

+0

ええ、私はそれがそうであるとは確信していません - 私はIEの循環参考事項を覚えていますそれは閉鎖と関係していた(私の頭の中に詰め込むための完全な詳細を決して得ることはできませんでした)が、私が読んだのは無名関数に関するより一般的な点だと思う。 –

0

これは、作成されたクロージャが原因で該当します。一般的なルールとして、この練習の最大の問題は、IE(特に古いバージョンのIE)のパフォーマンスに関する懸念です。これは、これらの問題を適切に処理するという実績があります。

関連する問題