5

このトピックを参照してください:ループ内で関数を作成しないでください。- jslint エラー

for ループ内で jquery .each(function () {...} をどのように処理しますか?「each」関数で「for」のコンテキストが必要であることを知っています。必要なすべてのパラメーターをfunction ループの外で宣言された関数ですが、私の観点からは、読みやすさに影響します。

何かご意見は?

前もって感謝します。

4

3 に答える 3

9

for 内のすべてのものが実際には最初に宣言された関数と同じコンテキストにあるため、for のコンテキストをループ内に保持できます。

Frits の例を見てみましょう。まず最初に、この完全な JSLint を (ループ エラーで呼び出された関数を除いて) 満足させましょう。

/*global console*/
var my_func, i, list;
for (i = 0; i < list.length; i+= 1) {
    my_func = function (i) {
        console.log(i);
    };
    my_func(i);
}

ループを反復するたびに、関数を再宣言していることに注意してくださいmy_func。それはクールではない!同じ関数を何度も再宣言するのはなぜですか?

次のように、以前に宣言します。

/*global console*/
var my_func, i, list;

my_func = function (i) {
    console.log(i);
};

for (i = 0; i < list.length; i+= 1) {
    my_func(i);
}

成功。これで、反復ごとに関数を作成しなくなりました。また、JSLint を使用すると、すべてのvar宣言を先頭に押し出すことで実現できるため、同じコンテキストを維持できます。


編集: @Flameが指摘しているように、jQueryeachで関数を早期に宣言する必要はなく、匿名関数を使用できますが、特に複数のeach呼び出しでロジックを再利用する場合は、早期に宣言することは悪い考えではありません. 主なポイントは、1.) 初期の宣言の実践にはまだ利点があること、および 2.) jQuery は引き続き関数に引数を送信すること (ここでは、私たちが呼び出しているものindex) を理解することですが、JSLint は送信しません(そしてすべきではありません) s で使用される無名関数について文句を言いますeach( jQuery ソースはこちら)。

匿名構造に慣れていると、最初は少し直感的ではありませんが、$.each(function() {});同じくらい簡単です。

/*global alert, $ */
$( "li" ).each(function( index ) {
    alert( index + ": " + $(this).text() );
});

... になる...

/*global $, alert */
var fnOutside = function(index) {
    alert( index + ": " + $(this).text() );
};
$( "li" ).each(fnOutside);

関数呼び出しにはパラメーターがないため、簡単に混乱するかもしれませんが、jQuery は "index" パラメーターを関数にプッシュしているものです。arguments命名を省略したい場合は、コンテキスト配列を取得して、そこにまだプッシュされていることを確認できます。

フィドルイゲ

つまり、for構造は新しいクロージャーを作成しません。それはあなたを心配しているかもしれません。問題ありません!

于 2013-03-27T22:54:10.247 に答える
4

ループ内の関数の問題は次のとおりです。

for (var i = 0; i < list.length; i+= 1) {
    function my_func(i) {
        console.log(i);
    }
    my_func(i);
}

次のように解釈されます。

var my_func;
for (var i = 0; i < list.length; i+= 1) {
    my_func = function (i) {
        console.log(i);
    }
    my_func(i);
}

可変巻上げのため。すべての宣言は、スコープ (つまり、関数) の先頭に移動されます。そのため、for ループで関数を定義することは実際には意味がありません。

for ループでカウンターにバインドする場合は、単純にクロージャーを作成します。

ただ明確にします:

$("..").each(function () {
    for(..) {
    }
});

結構です。

for(..) {
    $("..").each(function () {

    });
}

これは次と同等であるため、問題ありません。

var my_func;
for(..) {
    my_func = function () {
        // ..
    }
    $("..").each(my_func);
}
于 2013-03-27T17:05:50.123 に答える
2

問題はコードよりも警告にあるようです。ええ、警告なしで JSLint テストに合格するのは良いことですが、それらのいくつかは不合理であり、不要なコードのリファクタリングを引き起こす可能性があります。

この Q&A の議論は関連しています: JSLint または JSHint JavaScript 検証を使用する必要がありますか? 他の lint ツールは JSLint よりも柔軟に利用できるため、必ずしも Crockford の個人的なコーディング設定ではなく、個人的なコーディング設定で生産性を維持できます。

別のツールを使用して JavaScript をリントすることを検討し、コードの可読性や保守性を犠牲にしないことをお勧めします。

于 2013-03-27T17:12:57.457 に答える