2

思ったほどJavaScriptのコールバックが理解できていないようです。

次の例では、setTimeout 内の関数の各コピーが変数「index」の独自のコピーを参照すると考えられます。したがって、この例を実行すると、「zero」「one」「two」というアラートが生成されます。

var array = ["zero", "one", "two"];
var out = "";
for(var i = 0; i < 3; i++){
    var index = i;
    setTimeout(  function(){alert(array[index])},  1 );
}

ただし、インデックス変数のコピーは 1 つしかないようで、コールバック関数のすべてのコピーが同じ変数を指しているため、「2 つ」「2 つ」「2 つ」というアラートが表示されます。

次の類似した (私が考えた) Java の例は、予想どおり、「ゼロ」「1」「2」を出力します。

import java.util.ArrayList;
import java.util.List;


public class CallBacks {

  public static void main(String[] args) {

    String[] array = {"zero", "one", "two"};
    List<Callback> callBacks = new ArrayList<Callback>();
    for(int i = 0; i<3; i++){
      final String print = array[i];
      callBacks.add(
              new Callback(){
                public void execute(){
                  System.out.println(print);
                }
              }
      );
    }
    for(Callback cb : callBacks){
      cb.execute();
    }
  }

  private interface Callback{
    public void execute();
  }

}

js の例が機能しない理由を説明して、2 つの例で何が起こっているかを比較できますか?

4

3 に答える 3

1

indexループの繰り返しごとに変化します。必要なのはindex、ループの影響を受けないクロージャーに配置することです。

var array = ["zero", "one", "two"];
var out = "";
for(var i = 0; i < 3; i++) {
    (function(index) {
        setTimeout(  function(){alert(array[index])},  1 );
    })(i)
}
于 2009-01-15T15:17:36.533 に答える
1

JavaScript では、for ループには独自のスコープがありません。そのため、ループ内で作成した var は、ループ外で定義されたものと違いはありません。

于 2009-01-15T15:20:27.450 に答える
0

Private Members In JavaScriptは、クロージャーに関する私のお気に入りのリファレンスです。これは、JS オブジェクトでプライベート変数を提供するためのレシピとして書かれています (役に立つかもしれませんが、役に立たないかもしれません) が、その過程で、クロージャーが一般的に、特に JS でどのように機能するかについての優れた紹介が行われます。

comp.lang.javascript の FAQにも、クロージャに関する有益なセクションがあります。

クロージャーは混乱を招く可能性があるため、Rhino の本にある、私が遭遇した最短の有用なクロージャーの実例をまとめました。

ああ、まだコメントするのに十分な担当者がいません:)しかし、関数の周りに括弧を入れなければならない理由についての上記の質問を見ました。これは、無名関数をインラインで呼び出す場合にのみ必要です。たとえば、ここでは括弧が必要です。

(function (arg) {alert(arg);})('hi world');

関数を作成してすぐに呼び出すためです。ただし、後で使用するために名前付き関数を宣言するだけの通常のケースでは、括弧は必要ありません。

于 2009-01-15T16:53:30.943 に答える