3
for(var i=1; i<496; i++) {
    (function(num) {
        myApp.getTerm(num, function (term, def){
            myApp.quizlet[0].terms[num] = { term: term, definition: def};
        });         
    })(i);
};

forループ内でコールバックを使用して関数を呼び出しています。コールバック関数は、現在のループの反復iにアクセスする必要があります。私は上記の解決策を考えています。

このようなことをする他の方法はありますか?

4

5 に答える 5

2

呼び出す名前付き関数を定義する方が読みやすくなります。

myApp.getTermForQuizzlet = function(num){
    myApp.getTerm(num, function (term, def){
        myApp.quizlet[0].terms[num] = { term: term, definition: def };
    });         
};

for(var i=1; i<496; i++) {
    myApp.getTermForQuizzlet(i);
};

それ以外は何ができるのかわかりません。

于 2012-06-23T01:00:17.263 に答える
2

あなたがしていることは不合理ではなく、うまくいくはずです。純粋に読みやすさのレベルで、私は

for(var i=1; i<496; i++) {
    function get_callback(n) {
        return function(term, def) {
            myApp.quizlet[0].terms[n] = { term: term, definition: def};
         };
    }
    myApp.getTerm(i, get_callback(i));         
};

Function.bindの使用に慣れている場合:

function callback (n, term, def) {
    myApp.quizlet[0].terms[n] = { term: term, definition: def};
}
for(var i=1; i<496; i++) {
    myApp.getTerm(i, callback.bind(this,i));
}

最初の引数をにバインドすると、 and引数iを取る「カリー化」関数になります。termdef

そしてもちろん、この恐ろしいハックがあります、家でこれを試さないでください。

for(var i=1; i<496; i++) {
    try { throw i; }
    catch (i) {
        myApp.getTerm(i, function (term,def) {
             myApp.quizlet[0].terms[i] = { term: term, definition: def};
        });
    }
}
于 2012-06-23T01:08:11.937 に答える
1

ループ内の構造は、即時呼び出し関数式(IIFE)と呼ばれます。

IIFEは、たとえば、サイクルでイベントハンドラーを作成し、後で使用するために各イベントハンドラーのループ変数の現在の値をロックしたい場合に役立ちます。この「ロック」は、(字句または関数)クロージャと呼ばれます。定数、ローカル変数、および引数値(この場合、numIIFEの引数)を含む外部関数(この場合はIIFE)の字句スコープです。はループ変数の実際の値です) myApp.getTerm、外部関数(IIFE)の実行が終了した後でも、各内部関数オブジェクト(この場合はに渡されるコールバック関数)の内部状態の一部になります。

ですから、私はあなたがこれを正しく行うと思います。あなたの場合、IIFEを使用することは完全に有効な解決策です。

このパターンの興味深い例(クロージャのIIFE)は、JohnResigの継承の実装にあります。

// ...
(function(name, fn){
  return function() {
    // use name and fn here
  };
})(name, prop[name])
// ...
于 2012-06-23T01:01:40.800 に答える
1

ほとんどの場合、私はbulidtinループの代わりに反復関数を使用します。これらは、新しいブラウザとほとんどのJSライブラリで利用できます。

array.forEach(function(item, i){
    //We can freely use "item" and "i" in callbacks without worrying
    setTimeout( function(){ console.log(item, i) }, 1000 );
});

これは通常、forループバージョンよりも短く(少なくとも配列を反復処理している場合)、すぐに呼び出される関数などを追加することなく、「無料」でのforループのクロージャのバグを回避します。それ。

このメソッドの主な欠点は、「this」の使用、break、continue、returnステートメントの使用、および組み込みループをサポートしていないことと、ほとんどのライブラリに配列または辞書の反復用の関数のみが付属しており、それ以上のサポートがないことです。一般的なループスタイル。この種の高度な機能が必要になることはめったにありませんが、必要になったときは、通常、(あなたが行ったように)追加のクロージャを使用するか、一般的なパターンの場合は、独自のイテレータ関数を記述します。

var forLoop = function(i0, n, f){
    for(var i=i0; i<n; i++){
        f(i);
    }
};

forLoop(1, 496, function(i){
    myApp.getTerm(i, function(term, def){
        myApp.quizlet[0].terms[i] = { ... }
    });
});
于 2012-06-23T01:02:02.223 に答える
1

基本的にやりたいようです

  1. アプリ、myAppを作成します。
  2. プロパティ.quizをmyAppに追加します。
  3. プロパティ.termsを.quizに追加します。
  4. クイズの各用語について、各用語をその定義に関連付けるオブジェクトを作成します。

必要なプロパティを設定するには、次のようにします。

var terms = ['js', 'php', 'css', 'html', 'as3'];
var defin = ['about js', 'about php', 'about css', 'about html', 'about as3'];
var myApp = {};
myApp.quiz = new Array;
myApp.quiz[0] = [];
myApp.quiz[0].terms = new Array;

terms.forEach(function(ele, idx){
    myApp.quiz[0].terms[idx] = {term: terms[idx], def: defin[idx]};
})

ここで、任意のクイズの任意の用語にアクセスする方法が必要です。したがって、..などの関数を使用してそれを行うことができます。

function getTerm(qn, tn){
  return myApp.quiz[qn].terms[tn];
}
var q0t2 = getTerm(0, 2);
console.log(q0t2); // def: "about css", term: "css"

ここにあなたのニーズが何であるかはよくわかりませんが、これが私の最善の推測です。あなたの状況が私がここで使用している種類の方法に合わない場合は、詳しく説明してください。:)

于 2012-06-23T02:50:59.390 に答える