Почему одно закрытие JavaScript работает, а другое нет? - PullRequest
6 голосов
/ 27 июля 2010

Существует две версии, предположительно, когда пользователь щелкает первую ссылку, он предупреждает «1», а вторая ссылка «2» и т. Д.

Версия 1:

<a href="#" id="link1">click me</a>
<a href="#" id="link2">click me</a>
<a href="#" id="link3">click me</a>
<a href="#" id="link4">click me</a>
<a href="#" id="link5">click me</a>

<script type="text/javascript">
    for (i = 1; i <= 5; i++) {
        document.getElementById('link' + i).onclick = (function() {
            return function() {
                var n = i;
                alert(n);
                return false;
            }
        })();
    }
</script>

Версия 2:

<a href="#" id="link1">click me</a>
<a href="#" id="link2">click me</a>
<a href="#" id="link3">click me</a>
<a href="#" id="link4">click me</a>
<a href="#" id="link5">click me</a>

<script type="text/javascript">
    for (i = 1; i <= 5; i++) {
        document.getElementById('link' + i).onclick = (function() {
            var n = i;
            return function() {
                alert(n);
                return false;
            }
        })();
    }
</script>

Версия 1 не будет работать. Версия 2 будет. Я думаю, что знаю причину, почему, но хотел бы сравнить с объяснениями других людей, почему версия 1 не работает.

Ответы [ 3 ]

4 голосов
/ 27 июля 2010

Версия 1 не работает, потому что есть общая переменная "i" (в данном случае переменная global , потому что вы забыли var), которая используется при каждом нажатии"функция-обработчик, которую создает цикл.

Во второй версии вы создаете новую лексическую область видимости с маленькой функцией-оберткой.Это дает каждому обработчику «click» свое собственное личное «i».

3 голосов
/ 27 июля 2010

Во втором примере вы создаете переменную n = i;, которая задает значение i внутри функции onclick.Хотя в первом случае функция onclick по-прежнему использует глобальное значение i

, я бы предложил вместо этого использовать следующее:

  for (i = 1; i <= 5; i++) {
    document.getElementById('link' + i).onclick = (function(i) {
      return function() {
        alert(i); 
        return false;
      }
    })(i);
  }

В этом случае вы получите то же поведение, так какi будет локальной переменной для функции onclick в качестве аргумента.

0 голосов
/ 27 июля 2010

Первый не работает, потому что: я - часть каждого замыкания. После 5 итераций теперь я 6 из-за постфиксного оператора приращения. Каждый раз, когда вызывается обработчик события, он получает значение i из своей области закрытия, которая всегда равна 6.

Вторая часть работает: поскольку каждое замыкание создает копию i в n, n является частью каждого замыкания.

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