Сравнение обратных вызовов java и javascript - PullRequest
2 голосов
/ 15 января 2009

Кажется, я не так хорошо понимаю обратные вызовы JavaScript, как я думал.

В следующем примере я думаю, что каждая копия функции в setTimeout будет ссылаться на свою собственную копию переменной "index". Поэтому при выполнении примера должны появиться следующие предупреждения: «ноль», «один», «два».

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

Однако, похоже, что существует только одна копия индексной переменной, и все копии функции обратного вызова указывают на одну и ту же переменную, давая мне следующие предупреждения: «два», «два» «два».

Следующий аналогичный (я думал) пример в java печатает «ноль», «один», «два», как и ожидалось.

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 не работает, и, возможно, сравнить, что происходит в двух примерах?

Ответы [ 3 ]

1 голос
/ 15 января 2009

В javascript цикл for не имеет собственной области видимости, поэтому переменная, которую вы создаете внутри цикла, не отличается от той, которая определена вне его.

1 голос
/ 15 января 2009

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)
}
0 голосов
/ 15 января 2009

Приватные члены в JavaScript - моя любимая ссылка на замыкания. Он написан как рецепт для предоставления приватных переменных в объектах JS (может быть, полезно, а может и нет), но в процессе проходит отличное введение в работу замыканий вообще, особенно в JS.

FAQ по comp.lang.javascript также содержит полезный раздел о замыканиях.

Замыкания могут сбивать с толку, поэтому я собрал рабочий пример самого короткого полезного замыкания, с которым я столкнулся, , который был в книге Rhino.

О, и у меня пока недостаточно комментариев, чтобы комментировать :), но я видел ваш вопрос выше о том, почему вы иногда должны ставить скобки вокруг функций. Это необходимо, только когда вы вызываете встроенную анонимную функцию. Например, здесь необходимо указать круглые скобки:

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

Потому что вы создаете функцию, а затем немедленно вызываете ее. Но в обычном случае, когда вы просто объявляете именованную функцию для последующего использования, эти символы не нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...