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

    +155

    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
    function alertObj(obj) {
        var str = "";
        for(k in obj) {
            if (typeof obj[k] == "object") {
                str += k+":<br />";
                for(kk in obj[k]) {
                    if (typeof obj[k][kk] == "object") {
                        str += "--"+kk+":<br />";
                        for(kkk in obj[k][kk]) {
                            str += "----"+kkk+": "+ obj[k][kk][kkk]+"<br />";
                        }
                    } else {
                        str += "--"+kk+": "+ obj[k][kk]+"<br />";
                    }
                }
            } else {
                str += k+": "+ obj[k]+"<br />";
            }
        }
        alert(str);
    }

    Алерт объектов

    Запостил: DsTr, 22 Февраля 2013

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

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

        а так в лоб два уровня - проще и элегантнее не придумаешь.
        Ответить
        • пожалуй соглашусь) но я все равно предпочел бы рекурсию на тот случай если же мне понадобится все таки 3-й уровнь))
          Ответить
        • >но после добавления ограничения на рекурсию, после добавления индентации по уровню, решения становится длинее и выглядит намного менее элегантным

          А у меня все нормально.
          function f(obj, recCount) { 
            if ( ! recCount) return [];
            
            var res = [];
            
            for (var k in obj) {
              if (Object.prototype.toString.call(obj[k]) == '[object Object]') {
                res.push(k + ':');
                var sub = f(obj[k], recCount - 1);
                if (sub.length == 0) {
                  res.push('  ...');
                } else {
                  for (var i = 0, l = sub.length; i < l; i++) {
                    res.push('  ' + sub[i]);
                  }
                }
              } else {
                res.push(k + ': ' + obj[k]);
              }
            }
            
            return res;
          }
          
          var o = {
            'a': 1,
            'b': 2,
            'c': {
              'd': 3,
              'e': {
                'f': 4,
                'g': 5,
                'h': {
                  'i': 6
                }
              },
              'j': 7
            },
            'k': 8
          }
          
          console.log( f(o, 3).join("\n") );

          Количество строк кода такое же, как в вышеупомянутом ГК, масштабируемо как по глубине, так и по возможности заменить разделитель строк, никакой вечной рекурсии и грязных хаков.
          Ответить
          • вывод на рекурсии не очень полезный.

            пример:

            var x1 = {
              'a': 1,
              'b': 2,
            }
            var x2 = {
              'a': 1,
              'b': 2,
            }
            x1['b'] = x2;
            x2['b'] = x1;
            alert( f(x1, 5).join("\n") );


            вывод:

            a: 1
            b:
              a: 1
              b:
                a: 1
                b:
                  a: 1
                  b:
                    a: 1
                    b:
                      ...


            я в прошлом страдал тем что делал аналог перлового Data::Dumper. правда там у меня все объекты были одинакового "типа" и имели ключевое поле - проблем с их сравнением не было.

            пример желаемого вывода:

            var x1 = {
              'a': 1,
              'b': {
                 'a': 1,
                 'b': x1
               }
            }
            Ответить
            • >вывод на рекурсии не очень полезный.
              http://ru-swine.livejournal.com/292495.html
              Ответить
              • "горизонт завален"

                ага :)
                Ответить
                • Развалины горизонта: http://ideone.com/gsNLRM

                  P.S. С JS у меня плохо, не смейтесь над кодом, писал как мог ;)
                  P.P.S. Из-за линейных поисков производительность должна быть отвратной O(n^2), но в js походу иначе никак.
                  Ответить
                  • > if (proto == '[object Object]' || proto == '[object Array]') {
                    хах
                    Ответить
                    • Скопировал выше у Scriptin ибо влом гуглить как правильно.

                      P.S. Такой метод достоен отдельного говнокода? ;)
                      Ответить
                      • excuses, excuses
                        Ответить
                      • Массивы и объекты не стоит одинаково обрабатывать:
                        http://stackoverflow.com/q/500504/484666
                        Ответить
                        • if (X.constructor == Array) { ...
                          Ответить
                          • > var a = [];
                            > console.log(a.constructor == Array, Object.prototype.toString.call(a) == '[object Array]');
                            true true
                            > a.constructor = {};
                            > console.log(a.constructor == Array, Object.prototype.toString.call(a) == '[object Array]');
                            false true
                            Ответить
                            • > Object.prototype.toString = function () { return "[та хуй єво знаит]" }
                              Ответить
                              • Да, действительно. Пуленепробиваемого способа, по всей видимости, нет.
                                Ответить
                                • Еще один "смертный" способ:

                                  http://ideone.com/xlE78Q
                                  Ответить
                  • круто.

                    НО: хахаха. хахаха. облом. перлового Data::Dumper в жаба скрипте не получится.

                    попробовал это заэвалить.

                    в `var zzz = { 'a': zzz }`, второе zzz все еще `undefined` потому что значение еще не присвоено.

                    аблом. :(

                    ЗЫ но все равно круто. потому что читабельно.
                    Ответить
                    • Нуу... мы сериализатор писали или отладочный дампер? ;)

                      Если сериализатор - можно попробовать не выводить ссылки на руты, а затем еще разок пробежаться по иерархии и догенерить присваивания.
                      Ответить
                    • Вот так должно заэвалиться: http://ideone.com/XUY9YB

                      P.S. Блджад, запятые забыл.
                      Ответить
                    • Быстрофикс: http://ideone.com/YWGus2
                      Теперь вполне исполняемый код. Нет только экранирования строк, но это тривиально и совсем влом реализовывать.
                      Ответить
            • Если вывод сделать в 2 фазы - не так и ужасно.

              Создаем два массива objects и roots. objects пустой, в roots пока лежит самый первый объект.

              На первом этапе сканируем объекты и вносим их в массив objects, а если объект уже там есть - то и в массив roots.

              На втором этапе выводим каждый root по-отдельности, подписав перед ним что-то типа var x1 =, а когда в поле какого-нибудь объекта попадается ссылка на что-то лежащее в roots, вместо нее проставляем x1.

              Если я не туплю - такой алгоритм должен нормально вывести произвольный граф, правда не особо шустро, т.к. в js нету нормального ассоциативного массива, но для отладки сойдет.
              Ответить
              • Все можно сделать и в одн проход, просто передавать в функцию таблицу с уже увиденными объектами. Примерно так, работает AMF, только он умеет сериализовать циклические графы, в отличие от JSON'a.
                Ответить
          • А чем JSON.stringify() не устроил? или функции тоже нужны? Вообще, в присутствии отладчика смысл написания такой функции от меня ускользает.
            Ответить
            • Две буквы: ИЕ
              Ответить
              • Та ну, даже в старых, где его действительно нет все равно найдется какая-нибудь Резиковская поделка, или инструмент коровы или еще что-то такое...
                Ответить
    • >$kkk
      Уголовно наказуемо же.
      Помни, RaZeR, за тобой могут следить!
      Ответить
    • http://pastebin.com/qPRzAmQz

      Когда-то пробовал написать сериализатор, зачем-то. Но так никогда им не пользовался. Сейчас подправил немножко, но тестировть все равно влом.
      Да, и все равно есть жабоскриптовские сущности, которые нельзя сериализовать, те же замыкания. Но об этом еще Стив Еге писал. Да, и это писалось для ноды, в ИЕ, скорее всего то, что касается функций не сработает. Да и вообще, как я уже говорил, это только идея, я так этим никогда и не пользовался.
      Ответить

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