Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   вопр. замыкание (https://javascript.ru/forum/jquery/8063-vopr-zamykanie.html)

Shaci 05.03.2010 01:30

вопр. замыкание
 
Что-то не могу понять, зачем здесь замыкание?:
Из книги jQuery Подробное руководство по продвинутому JavaScript
"Пример выводит имя тега и значение атрибута id текущего элемента,
создавая замыкание, после этого выводится значение атрибута id элемента, для которого предназначено событие."

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html id="greatgreatgrandpa">
  <head>
    <title>DOM Level 0 Bubbling Example</title>
    <script type="text/javascript" src="../scripts/jquery-1.2.1.js">
    </script>
    <script type="text/javascript">
      $(function(){
        $('*').each(function(){
          var current = this;
          this.onclick = function(event) {
            if (!event) event = window.event;
            var target = (event.target) ?
                         event.target : event.srcElement;
            say('For ' + current.tagName + '#'+ current.id +
                ' target is ' + target.id);
          }
        });
      });

      function say(text) {
        $('#console').append('<div>'+text+'</div>');
      }
    </script>
  </head>

  <body id="greatgrandpa">
    <div id="grandpa">
      <div id="pops">
        <img id="vstar" src="vstar.jpg"/>
      </div>
    </div>
    <div id="console"></div>
  </body>
</html>



Можно же так, и вроде нет в этом криминала:
<script type="text/javascript">
      $(function(){
        $('*').each(function(){
          //var current = this;
          this.onclick = function(event) {
            if (!event) event = window.event;
            var target = (event.target) ?
                         event.target : event.srcElement;
            say('For ' + this.tagName + '#'+ this.id +//замыкание не требуется
                ' target is ' + target.id);
          }
        });
      });

      function say(text) {
        $('#console').append('<div>'+text+'</div>');
      }
    </script>

Kolyaj 05.03.2010 08:31

Это вы кэширование this в локальной переменной замыканием назвали?

micscr 05.03.2010 08:35

1-ый пример:
var current = this;

2-ой пример(твой):
this.tagName

т.е. указывают на один и тот же объект.
Этот пример из книги просто чтобы продемонстрировать что такое замыкание.

Kolyaj 05.03.2010 08:55

А, ну у вас просто совпало, что в обоих контекстах this указывает на один и тот же объект. А так бы ваш вариант не работал.

Shaci 05.03.2010 12:02

Цитата:

Сообщение от Kolyaj (Сообщение 46832)
Это вы кэширование this в локальной переменной замыканием назвали?

Ну вообще говоря, да :)
Хотя, если по чесноку, то тут после вызова внешней функции , сохраняется её объект вызова, во внутреннюю ф-цию
"передается ссылка на объект с локальными переменными [[scope]] внешней функции", т.е. внутренняя ф-ция теперь может в любой момент через этот объект получить локальные переменные внешней ф-ции, т.е. current.

Цитата:

Сообщение от micscr (Сообщение 46833)
1-ый пример:
var current = this;

2-ой пример(твой):
this.tagName

т.е. указывают на один и тот же объект.
Этот пример из книги просто чтобы продемонстрировать что такое замыкание.

просто пример такой, что из него не видно логики использования замыкания, т.к. можно и без него обойтись

Цитата:

Сообщение от Kolyaj (Сообщение 46834)
А, ну у вас просто совпало, что в обоих контекстах this указывает на один и тот же объект. А так бы ваш вариант не работал.

угу

Kolyaj 05.03.2010 12:08

И да, this замыкания плохо иллюстрирует. Хорошо их иллюстрирует навешивание обработчиков или вызов асинхронных функций в цикле
for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        alert(i);
    }, (i + 1) * 1000);
}


for (var i = 0; i < 3; i++) {
    (function(index) {
        setTimeout(function() {
            alert(index);
        }, (index + 1) * 1000);
    })(i);
}

Shaci 05.03.2010 12:21

[quote=Kolyaj;46847]И да, this замыкания плохо иллюстрирует. Хорошо их иллюстрирует навешивание обработчиков или вызов асинхронных функций в цикле
for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        alert(i);
    }, (i + 1) * 1000);
}

Да, у этих 3-х ф-ций общий объект вызова, поэтому они и на одно i ссылаются, равное 3 к концу цикла.


Часовой пояс GMT +3, время: 02:34.