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

    +153

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    window.onload = function()
     {
         m1 = new Matrix('matrix1', 20, 20);
         m1.create();
    
        var square = new Square(1, 2, 'right');
         square.create();
    
        setInterval(square.move, 50);
     }
    
    function Square(row, col, course)
     {
     this.body = [row, col];
    
     this.course = course;
    
     var that = this; // <-- 100500 iopta !!!
    
     this.create = function()
     {
       m1.setCell(that.body[0], that.body[1], true);
     }
    
     this.move = function()
     {
       var last_body = that.body;
       switch(that.course)
       {
        case 'right':
        that.body[1]++;
        break;
        case 'left':
        break;
        case 'down':
        break;
        case 'up':
        break;
       }
    
      m1.setCell(last_body[0], last_body[1], false);
       m1.setCell(that.body[0], that.body[1], true);
     }
     }

    здесь вам не тут, понял, да !

    Запостил: bahamot, 04 Мая 2014

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

    • http://ideone.com/np3jJG
      Хм, а зачем that?
      Ответить
      • Чтобы во вложенной функции обращаться к this внешней функции. Так в JS работает this.
        Ответить
        • А через this никак? :)
          Ответить
          • А ты попробуй, и посмотри, что выйдет.
            Ответить
            • показать все, что скрытоКаждой суке - по минусу.
              Ответить
            • Так я попробовал, по ссылки перейди. Контекст сохраняется, that не нужен!
              Ответить
              • Но не глубже одного раза что ли (но я в js не разбираюсь, только тот рогалик на нем прошел)?
                http://ideone.com/51KoTe
                Ответить
                • В js каждая функция имеет неявный параметр this, который является ссылкой на объект, на котором функция вызвана.

                  Если взять какой-нибудь сишарп, там obj.Method по сути создаст делегат, который захватит объект obj, а при вызове будет вызывать соответствующий метод объекта. Аналогичный механизм есть в питоне.

                  В js такого нет, там obj.Method по сути является крестовым указателем на метод, которому ещё нужно передавать this. Поэтому автор кода в топике и создаёт that, чтобы замыкание, созданное в конструкторе, всегда использовало тот объект, для которого оно было сконструировано.
                  Ответить
      • > Хм, а зачем that?
        если использовать square.func без скобок, контекст теряется.
        http://ideone.com/cA1zkY
        Ответить
        • А тут that кроме строки 9 и не нужен.
          setInterval(square.move, 50);
          Ответить
          • я и не спорю, наоборот, всячески против замыканий в конструкторе. Лучше явно использовать bind.
            Ответить
            • А bind это случаем не то же самое замыкание?
              Ответить
              • Разумеется, замыкание, только оно создаётся один раз в том месте, где требуется, а не для всех объектов и всех методов.
                Ответить
    • http://javascript.crockford.com/private.html
      By convention, we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.

      Но здесь это почти не нужно.
      function Object(value) {
        var that = this;
        this.value = value;
        
        this.getValue = function() { // публичный метод
          return this.value; // функция принадлежит объекту =>
          // установлен правильный this; that не нужен,
          // кроме использования в отдельности от объекта:
          // var f = (new Object(5)).getValue; var v = f(); // that нужен
        };
        
        function setValue(value){ // приватный метод -- это просто функция
          that.value = value; }; // this === window или undefined в новом жс
          // that нужен
        }
      }
      Ответить
    • Когда последний раз писал на ж.скрипте что-то серьезнее двух строчек, написал прототип у которого конструктор сразу после создания привязывал все "методы" к созданому экземпляру.
      Писать в каждой функции that - это какой-то китайский подход.
      Ответить
      • > привязывал все "методы"
        Как в примере анонимба чуть выше?
        Ответить
        • Не, используя это: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
          Или самописный вариант, если вышеописаное недоступно (в скриптах на Анте, например).

          Да, самописный вариант так же понадобится при наследовании "методов", т.как нужна будет процедура по извлечению непривязаного метода и созданию новой привязывающей функции.
          Вобщем, как обычно, ж.скрипт стандарт думает только на один шаг вперед, чтобы не переутруждаться и оставить хороший задел для следующих поколений писателей говностандарта.
          Ответить
        • Есть еще другой вариант: самому организовать ОО, не опираясь на возможности ж.скрипта. У меня даже где-то были начала КЛОС + примитивной системы типов, которая могла, по крайней мере теоретически, в перегрузки и ошибки типизации.
          Ответить
        • http://vpaste.net/U9PMo
          Кстати, если интересно. Простая объектная система, в принципе работающая как в ж.скрипте, только с нормальной привязкой this, и без еботни с прототипами.
          Она не очень оптимальна, т.как унаследованые методы копируются (зато быстрее, чем искать по цепочке), но это можно доработать.
          Особо не тестировал, но на первый взгляд (и для той мелочи, которую писал) - хватало.
          Ответить
          • Она не очень оптимальна, т.как унаследованые методы копируются
            ИМХО это самый лучший вариант.
            Ответить
    • Создём замыкания с каждым конструктором. У клиента же память безмерная, чего её экономить.
      Ответить
    • Снова по минусу.
      Ответить

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