1. JavaScript / Говнокод #14344

    +154

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    var i1id = setInterval(function () {
                $('#step-2 table.step-1-top-tabs td#images').addClass('tab-selected');
                $('#step-2 table.step-1-top-tabs td#images').click();
                clearInterval(i1id);
            }, 100);

    О функции setTimeout не слышали.

    Запостил: begmst, 10 Января 2014

    Комментарии (25) RSS

    • Странно, обычно наоборот, setInterval мутят через setTimeout...
      Ответить
      • Вот такой, вариант, кстати, бывает и оправдан:
        function f() {
          function asynchronousCallback() {
             function anotherAsynchronousCallback() {
                setTimeout(f, 5000);
            }
          }
        }
        setTimeout(f, 5000);

        Чтобы, скажем, из-за глючного удаленного сервиса не накапливалась куча висящих AJAX-запросов.
        Ответить
    • А в JS вообще так можно - из функции обращаться к локальной переменной, не инициализированной на момент объявления функции?

      В Java нельзя, по понятным причинам.
      Ответить
      • в js наоборот, надо, чтобы было к чему обращаться на момент обращения
        Ответить
      • В жабе переменные захватываются по значению (отсюда и защита от дурака требование на final).
        В жс (и в шарпе) - по ссылке, и значение можно поменять в любое время, читаться будет всегда актуальное. Поэтому объявления вполне достаточно.

        Из-за этого в жс нельзя создавать пачку замыканий в цикле. Ну вернее можно, но выглядит это как куча говна не очень красиво.

        В шарпе тоже можно словить баг с созданием замыканий в цикле, но там он легко контрится из-за нормальных скопов.
        Ответить
        • В новой жабе сделали для замыканий неявный final.
          То есть теперь можно не писать, но при попытке поменять значение будет ругаться.
          Не знаю хорошо это или плохо.

          Но в целом мне подход с захватом только констант и мутирование через кучу кажется более удобным, наглядным и избавляющим от граблей.
          Ответить
          • > но при попытке поменять значение будет ругаться
            Это ж, вроде как, просто защита от дурака... Чтобы народ не задумывался, какое именно значение будет захвачено - то, которое было в момент описания класса, или то, которое было в момент его инстанциирования.

            Раз уж убрали требование на final, так, имхо, стоило идти до конца: просто добавили бы в спеку "значения захваченных переменных будут такими же, как в момент вызова new". Ну а с лямбдами и анонимными классами неоднозначности вообще никакой нет.
            Ответить
          • Или там как раз снаружи менять можно (никак не влияя на захваченные значения), а ругаться будет при попытке поменять значение изнутри "замыкания"?
            Ответить
            • Вообще походу нельзя менять. Просто final писать не обязательно.
              Ответить
        • А еще в .net 4.0

          foreach(var x in IEnumerator )
          {
          }

          эквивалентен в .Net 3.0

          foreach(var Y in IEnumerator )
          { var x = Y;

          }

          дабы замыкания строились кошерно.

          Так же менять значение x во время итерации нельзя
          Ответить
          • > Так же менять значение x во время итерации нельзя
            И это правильно. Ибо его все равно в таких циклах никто не меняет.
            Ответить
            • Ну да, не для того итераторы созданы.
              Ответить
              • показать все, что скрыто████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████
                Ответить
            • показать все, что скрыто████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ████████████████████████████████████████ ███
              Ответить
        • Замыкания как замыкания, что страшного в
          for(var key in object)!function(val){
            setTimeout(function(){
              console.log(val);
            }, 1000);
          }(object[key]);

          или тем более
          array.forEach(function(val){
            setTimeout(function(){
              console.log(val);
            }, 1000);
          });
          ?

          Ну или даже так -
          for(var key in object){
            setTimeout(console.log.bind(console, object[key]), 1000);
          }
          Ответить
          • Ну не знаю... мне, как не часто пишущему на жс, не нравится оборачивание в лишнюю функцию только ради скопа...
            Ответить
            • Да, лишний слой функции не очень смотрится (надеюсь, с => в ES6 будет менее многословно), но зато выглядит относительно логично. В питоне, если не ошибаюсь, в аналогичной ситуации надо знать больше правил.
              Ответить
              • В питоне есть очень хитрый чит:
                def generate():
                    a = []
                    for i in range(0, 5):
                        def f(i=i):
                            print(i)
                        a.append(f)
                    return a
                Ну и каррирование через partial, по аналогии с жсным bind.
                Ответить
                • По есть внутри скопа внешняя i блочится внутренней i которая определяетя через внешнюю. Оригинально
                  Ответить

    Добавить комментарий