75

これらは主に私が疑問に思っていることのほんの一部です。誰かがそれらについてもう少し洞察を与えることができるかもしれません。私がこれまでに気づいたことも共有します!

私が最初に疑問に思っていたのは...違いはありますか、それとも使用する理由はありますか:

$('element').each(function (i, el) { });

- 対 -

$.each($('element'), function (i, el) { });

jQueryのドキュメントを見ると、どちらか一方の韻や理由がわかりません(インスタンスや、一方が他方よりもできる追加のことを知っているかもしれません.

しかし、もっと重要なことに、私はここで速度に関心があります

// As opposed to $.each() looping through a jQuery object
// -- 8x faster 
for (var i = 0, $('.whatever').length; i < len; i++) {
    $('.whatever')[i] // do stuff
}

このjsFiddle DEMO hereをチェックすると、速度の違いは基本的にどちらでも同等であることがわかりますが、さらに重要なことに、常にfor()ループを使用する必要があると感じています...

私は単なる単体テスト (5 つの異なるシナリオ関数のそれぞれを 50,000 回ループ) で、一連のリスト アイテムを単純にループし、data-newAttr特別なことは何も設定しませんでした。


質問 :: 私の最大の質問は、オブジェクトを反復処理するときに常にfor ループを使用しないのはなぜですか?? $.each() を使用する意味さえありますか? jQuery オブジェクトを通過するときでも、常に for() ループを使用しますか?

jsFiddle DEMOはこちら

Function type:                  Execution Time:
_testArea.each() + $(this)               1947   <-- using $(this) slows it down tremendously
$.each()         + $(this)               1940
_testArea.each() + el(plain JS)           458   <-- using the Element speeds things up
$.each()         + el(plain JS)           452
for() loop       + plainJS[0] iteration   236   <-- over 8x faster

ちょうど私の2セント。:)

4

6 に答える 6

48

One thing that .each() allows you to do that can't be done with a for loop is chaining.

$('.rows').each(function(i, el) {
    // do something with ALL the rows
}).filter('.even').each(function(i, el) {
    // do something with the even rows
});

I played around with your JSFiddle to see how chaining would influence performance in cases where you have to loop through subsets of the original set of matched elements.

The result wasn't all that unexpected, although I think the overhead of end() was exaggerated here because of the combination of few elements and many loops. Other than that: plain JS loops are still slightly faster, but whether that weighs up to the added readability of .each() (and chaining) is debatable.

于 2012-08-09T16:11:43.277 に答える
22

.each()(すべてのオブジェクトに対して無名関数を呼び出すため)自動ローカルスコープを使用できます。つまり、すべての反復でさらに多くの無名関数/クロージャ/イベントハンドラーなどを作成する場合は、次のことを行う必要はありません。ハンドラーが変数を共有することを心配してください。つまり、JavaScriptは、ローカルスコープに関しては他の言語のようには機能しませんが、どこでも変数を宣言できるため、ときどきだまされる可能性があります。

言い換えれば、これは間違っています:

var idx,el;
for (idx = 0; idx <someObjectArray.length; idx++){
   el = someObjectArray[idx]
   el.someEventHandler(function(){  
       alert( "this is element " + idx);
   }); 
}

これらのオブジェクトのいずれかがこのループの後に「someEvent」を呼び出すときはいつでも(これは構成されていることに注意してください)、アラートは常に最後に割り当てられたものを通知しidxますsomeObjectArray.length

適切なインデックスを確実に保存するには、ローカルスコープを宣言し、変数を作成して、その変数に割り当てて使用する必要があります。

var idx,el;
for (idx = 0; idx <someObjectArray.length; idx++){
   el = someObjectArray[idx];
   (function(){
       var localidx = idx;
       el.someEventHandler(function(){  
           alert( "this is element " + localidx);
       }); 
   })();
}

ご覧のとおり、それは地獄のように醜いですが、うまくいくはずです。各イベントハンドラーは、独自のコピーを取得しますlocalidx

今それをと比較してください.each()

$(someObjectArray).each(function (idx, el) { 
   el.someEventHandler(function(){  
       alert( "this is element " + idx);
   }); 
});

ずっと簡単ですね。

于 2012-08-09T16:28:53.167 に答える
9

jQuery.each と for ループ

jQuery.each の利点:

  • jQuery コード (チェーンとスタイル) にうまく適合します。
  • スコープについて心配する必要はありません (イテレータとオブジェクトへの参照は永続的です)。
  • 普遍的に使用できます (すべての種類のオブジェクトとオブジェクト キーの反復処理)。

for ループの利点:

  • 高パフォーマンス (ゲーム/アニメーション/大規模なデータセット向け)。
  • イテレータの完全な制御 (項目のスキップ、リストからのスプライス項目など)。
  • jQuery に依存しないため、for ループは常に機能します。
  • 他のほとんどの同様の言語と同じ使い慣れた構文。

サンプルコード

これは、リストを反復処理する方法のサンプル コードです。

var list = ['a', 'b', 'c', 'd', 'e', 'f'];

jQuery.each:

$.each(list, function(i, v)
{
    // code...
});

クロージャのない for ループ:

for(var i=0,v,n=list.length;i<n;i+=1)
{
    v = list[i];
    // code...
}

クロージャー付きの for ループ:

for(var i=0,n=list.length;i<n;i+=1)
{
    (function(i, v)
    {
        // code...
    })(i, list[i]);
}

注: 標準の for ループのみを使用し、必要な場合にのみクロージャーを使用することをお勧めします。ただし、とにかくコードが Javascript よりも jQuery に似ている場合は、$.each. パフォーマンスの問題が発生した場合は、後でいつでも調べることができます。

于 2014-09-10T22:56:01.013 に答える
5

http://jsperf.com/forloops3の前に、いくつかの簡単なパフォーマンステストを実行しました。プレーンで古いものfor loop(可能な場合)に固執することが道のりのようです:)

于 2012-12-28T20:04:01.243 に答える
4

私があなたのリンクに行ったとき、私が得た2つの数字があります:

$.each() + el(plain JS) 401
for() loop + plainJS[0] iteration   377

違いがそれほど小さい場合は、最も読みやすいものを使用しますが、非常に長い時間が必要な場合は、最終的に最速のものを使用する必要があるかもしれません.

上記の 2 つの 3 つの異なるメソッドを使用するようにプログラムを作成し、新しいバージョンの JavaScript にある foreach を使用するようにプログラムを作成することをお勧めします。これをサポートしていないブラウザーでは、プロトタイプとして追加できます。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach

要件が何であるか、およびプログラムが何をするかを知っているので、独自のテストを作成し、サポートするブラウザー全体で要件を満たしていることを確認してください。

あなたの最初の質問については、$('element').each読みやすいのでそうしますが、それは私の意見です。

于 2012-08-09T16:17:38.540 に答える