2011-07-20 1 views
2

だから、私はイベントリスナーを添付するための大きな要素セットを持っているとしましょう。例えば。クリックすると各行が赤くなるようにするテーブル。javascriptでは、インライン関数を定義する際のトレードオフとリファレンスとして渡すことのトレードオフは何ですか?

私の質問は、これらの中で最も速く、メモリを最低限に抑えるものです。私はそれが(通常)トレードオフであることを理解しているので、私はそれぞれに最適なオプションを知りたいと思っています。テーブルの例を使用して

、のは、すべての行要素のリストがあります言わせて、「rowList」:

オプション1:

for(var r in rowList){ 
    rowList[r].onclick = function(){ this.style.backgroundColor = "red" }; 
} 

私の直感では、これが最速であるということですそれぞれの行リストには関数の独自のコピーがあり、onclick関数が大きい場合に重大になる可能性があるため、ポインターコールは少なくて済みますが、最もメモリが集中します。

オプション2:(!ああ、もう一つのポインタ参照)

function turnRed(){ 
    this.style.backgroundColor = "red"; 
} 
for(var r in rowList){ 
    rowList[r].onclick = turnRed; 
} 

私は、これは上記のものよりもほんのteensy少し遅くなるだろう推測しているが、はるかに少ないメモリ集約ブラウザは関数の1つのコピーを追跡するだけでよいからです。

オプション3:

var turnRed = function(){ 
    this.style.backgroundColor = "red"; 
} 
for(var r in rowList){ 
    rowList[r].onclick = turnRed; 
} 

私は、これはオプション2と同じであると仮定し、私はちょうどそこにそれをスローするようにしたかったのです。対

$('tr').click(function(){this.style.backgroundColor = "red"}); 

:とjqueryの

同じ質問:JavaScript differences defining a function

ボーナスセクション:これとオプション2との違いは何であるか疑問に思ったものについては

function turnRed(){this.style.backgroundColor = "red"}; 
$('tr').click(turnRed); 

と:

は、より高速な方法であると、より少ないメモリを使用しています

http://jsperf.com/function-assignment

オプション:

+0

10k行の表を作成し、プロファイラーを使用して、人間がどのくらい速いかの違いの影響を制限するために、おそらくテストをスクリプト化するためにSeleniumを使用します。 ChromeとFirefoxには素晴らしいプロファイラーがありますが、影響についてはIE8/9と似たようなことを考えてみてください。 –

答えて

5

はここにあなたの答えです。その理由は、オプション1がループの繰り返しごとに新しい関数オブジェクトを作成するためです。

+0

+1!私はJSPerf.comについて知りませんでしたが、これからもこのような質問に答えるために使用します。ありがとう! –

+0

Chrome 11では速度の差が最も顕著です。Opera11、IE8、FF5の2つの方法のパフォーマンスの差は10%未満です。 – jfriend00

+0

@ jfriend00そうですね。 –

2

メモリの使用量に関して、Option 1は、配列の各行に対して別個の関数クロージャを作成しています。したがって、このアプローチでは、Option 2Option 3よりも多くのメモリを使用します。これらの関数は単一の関数を作成し、その関数への参照を渡します。

私はこの同じ理由で、Option 1が3つの中で最も遅いものと期待しています。もちろん、実際のパフォーマンスとメモリ使用量の差はおそらくかなり小さいでしょうが、最も効率的なものをお望みなら、Option 2またはOption 3のどちらかを選んでください(どちらも同じですが、 2つはturnRedが表示される範囲です)。

jQueryの場合、3つのオプションはすべて同じメモリ使用量とパフォーマンス特性を持ちます。どのような場合でも、インラインで定義するかどうかに関わらず、単一の関数参照を作成してjQueryに渡しています。

あなたの疑問に抱かれていない重要な点は、たくさんのインライン関数を使用すると、コードをすぐに判読できない厄介なものにしてしまい、メンテナンスが難しくなることです。あなたの関数には1行のコードしかないのでここでは大したことではありませんが、一般的なルールとして関数に2〜3行以上が含まれている場合は、インラインでの定義を避けることをお勧めします。代わりに、Option 2またはOption 3のように定義してから、参照を渡します。

+0

jQueryの場合、3つのオプションはすべて同じメモリ使用量とパフォーマンス特性を持ちます。どのような場合でも、インラインでもそうでなくても、jQueryへの単一の関数参照を作成して渡しています._ これは知っていると便利です!ありがとう! –

+0

+1すばらしい答え!私はしばしばスコープの理由のためだけに 'オプション3 'を使います。そして、グローバルなスコープは、必要のない小さな関数のヒープ全体で汚染されていません。もし私ができるならば、インライン関数のノートが読めない混乱になってしまうために私は+2を払うでしょう。 –

関連する問題