4

理論上のパフォーマンスに関する小さな質問:

私が次のようなものを持っている場合:

$(".somediv").each(function() {
   // perform some heavy stuff here
});

匿名関数のコードを次のような名前付き関数にリファクタリングした場合、コードの実行は速くなりませんか?

f = function() {
   // perform some heavy stuff here
};

$(".somediv").each(f);

どういうわけか、匿名関数が各ループ内で毎回再作成される可能性があることを私に伝えるこの不合理な疑問がありますか?

4

4 に答える 4

3

パフォーマンスが心配な場合は、使用しないでください.each()forループまたはループを使用してコレクションの内容を反復し、while関数呼び出しをまったく行わない方が.each()、各アイテムの結果の関数呼び出しで使用するよりもはるかに高速です。

あなたの質問に答えると、匿名関数は名前付き関数よりも遅くなりません。相違点は、実行前の解析時に解決されます。

この jsPerfは、単純なループがhttp://jsperf.com/each-vs-for-loop-mineforよりもほぼ 10 倍高速であることを示してい.each()ます。

于 2012-08-06T07:21:50.013 に答える
1

コードを考えてみましょう (jquery 1.7.1):

// "public" each
each: function( callback, args ) {
    return jQuery.each( this, callback, args );
}

// "local" each
each: function( object, callback, args ) {
    // [...]

    if (args) {
        // [ args is for internal use ...]
    // A special, fast, case for the most common use of each
    } else {
        if (isObj) {
            for (name in object) {
                if (callback.call(object[name], name, object[name]) === false) {
                    break;
                }
            }
            // [...]

ご覧のとおり、callbackは直接参照および使用されます。関数のコピーはありませんcallback。それにもかかわらず、 jQueryが関数をコピーした場合、提案された回避策はjQuery内で同じ動作を生成します。

注: JavaScript では、関数はオブジェクトです。ある関数宣言構文が別の関数宣言構文と異なる動作をする「不合理な」理由はありません。唯一の違いはスコープです。提案された回避策は、関数をグローバルなものにしますが、他の匿名関数はeach呼び出しに対して「ローカル」です

于 2012-08-06T07:22:21.627 に答える
0

再作成されるのではなく、一度作成されると、参照が関数に渡されます$.each()。次に、その関数はその参照を介して無名関数を呼び出します。

違いがあったとしても、他の誰かがあなたのコードを読んでいるときに最も理解しやすいパターン以外に、別のパターンを使用することを保証するほど重要ではないと思います。コードにパフォーマンスの問題が発生した場合は、それを測定してボトルネックを見つけます。それはほぼ間違いなくこのようなものからではありません。

于 2012-08-06T07:19:31.037 に答える
0

.each() と for ループの比較を次に示します。

http://jsperf.com/jquery-each-perf-test2/2

于 2012-08-06T07:27:27.387 に答える