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

    +156

    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
    var renderHours = function(s){
            var html = '<ul>';
            var json = Ext.decode(s);
            for(i in json)
                if(typeof json[i].from_d != 'undefined')
                    html += '<li>с <b>'
                        + hours[json[i].from_d][1]
                        + '</b> -  по <b>'
                        + hours[json[i].to_d][1]
                        + '</b> ('
                        + json[i].from_h +':'+ json[i].from_m +'-'
                        +json[i].to_h +':'+ json[i].to_m +')</li>';
                
            return html+'</ul>';
        };

    Вот такое попалось

    Запостил: Sulik78, 11 Июля 2012

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

    • Даты датами, я вот чего не могу понять, и это находится практически в любом фрагменте кода на Яваскрипте длиннее 32 строчек:
      typeof x == 'undefined'
      Зачем? Почему нужно сравнивать со строкой, когда x === undefined делает то же самое, но напрямую.

      ЗЫ. Было бы интересно, если бы там передавалось что-то типа { from_d : "<img src='site.com/32.jpeg'>" }
      Ответить
      • Некоторые браузеры матерятся(~ились?) на прямое сравнение с undefined.
        Ответить
        • > Некоторые браузеры
          Под некоторыми браузерами, как обычно, подразумевается IE?
          Ответить
      • Кстати, да. На многих сайтах про undefined говорят (пример со StackOverflow, жутко заплюсованный комментарий):
        >It's not a keyword at all, but a variable that (most of the time) happens to be undefined

        Открываю, например, MDC и вижу:
        >undefined is a property of the global object, i.e. it is a variable in global scope.
        >Implemented in JavaScript 1.3 (это было давно)

        WTF?
        Ответить
        • undefined это единственный экземпляр типа undefined (причём undefined == null && undefined !== null). А typeof пишут потому, что всеми любимый ie раньше не определял этого экземпляра.
          Ответить
        • Ну так и NaN точно так же, да и вообще все, что находится в глобальной области видимости: String, Number, Date, Object, Array, isNaN, alert и т.д. являются такими же сущностями. Кроме того, undefined - константа по факту, а не переменная, и хотя присвоение ему "работает", результат остается прежний.

          Если это почему-то не работало в ИЕ - в какой версии? Это почти наверняка что-то очень древнее (хз, у меня нет ИЕ и проверить не в чем).

          Что сейчас по этому поводу говорит МСДН:

          The undefined constant is a member of the Global object, and becomes available when the scripting engine is initialized. When a variable has been declared but not initialized, its value is undefined.
          
          If a variable has not been declared, you cannot compare it to undefined, but you can compare the type of the variable to the string "undefined"
          
          The undefined constant is useful when explicitly testing or setting a variable to undefined.


          Ну так они же говорят про незадекларированные переменные! json[i].from_d никакая не переменная вообще же.
          Ответить
      • Если не принимать во внимание абстрактные измышления о том, что нужно применять методы по назначению и в зависимости от смысловой нагрузки, то в приведённом коде это действительно не имеет значения.

        Но вообще сакральная суть typeof в том, что в случае отсутствия переменной как таковой, он не кинет ошибки, а честно напишет 'undefined':
        var eh;
        typeof eh === 'undefined'; //true
        eh === undefined; //true

        typeof neh === 'undefined'; //true
        neh === undefined; //ReferenceError: neh is not defined
        Ответить
        • Дык я же пытаюсь сказать, что в коде выше не проверяют переменные, проверяют наличие значения и / или существования свойства у какого-то динамического объекта. Неужели ИЕ в таком случае выдает ошибку? Что-то мне как-то тяжело в это поверить... А проверять переменные на то, что сам же их создал или нет - ну, не знаю, это либо исключительный крайний случай паранои, либо лень пролистать код до начала и посмотреть, а объялялась ли переменная или нет. Т.е. конечно, возможны ситуации, когда кто-то через какие-то махинации объявил неявно переменную, но обычно же не ищем чужую а свою, или, если чужую, то знаем, что ищем...

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

            Мне кажется, это имеет смысл при работе с глобальным скопом. Например, для эмуляции нэймспэйсов:
            if (typeof com == "undefined") {
              com = {};
            }
            if (!com.hasOwnProperty("acme")) {
              com.acme = {};
            }
            com.acme.doSomething = function () { /* ... */ }
            Ответить
            • А когда такая неуверенность возможна? - правильно, только тогда, когда такой код вызывается много раз из разных мест. И капитан в таком случае подcкажет, что его, очевидно, лучше завернуть в функцию и загрузить до того, как любой другой код им воспользуется, а заодно вместе с ним объявить и переменную com или что там. Что поможет не делать лишних проверок.

              hasOwnProperty в этом случае - плохо потому что собирает только свойства объявленные этим объектом. Т.е. если вы захотите создать пакет с, например, именем __proto__ или что-нибудь такое - может быть облом.

              Но вообще, сама по себе идея плохая, т.как создавая такие псевдо-пакеты вы работаете против минимизатора, т.как он уже не сможет повыбрасывать эти имена. Кроме того, вы работаете против других библиотек, и мешаете им использовать минимизатор. Нормальным в Яваскрипте было бы, как раньше в ПХП или в том же эЛиспе - префиксы к функциям. Минимизатор будет с таким хорошо работать, не создаются лишние сущности загрязняющие глобальный неймспейс и т.д.

              Когда module заработает - возможно что-то такое в нем будет, а пока я бы такого не делал (но, увы, это частая практика).
              Ответить
              • дело в том, что проект может использоваться множество различных библиотек от независимых разработчиков:
                com.ibm.doSomething();
                com.oracle.doSomething();
                Очевидно, объект com должен быть создан только один раз, причём точно не тем, кто использует эти библиотеки. Если он создавался только в одной библиотеке, была бы зависимость от порядка подключения.

                Я не утверждаю, что нэймспейсы - хорошая идея. Просто они имеют место быть.

                P.S. я знаю, как работает hasOwnProperty. как раз я и не хочу подцепить объект из прототипа, я хочу объявить его именно в нэймспейсе com.
                Ответить
                • Хз, я бы просто этого не делал, это еще и всякие ошибки безопасности потом, да и вообще идея совместно использовать объект с какой-то другой библиотекой, которая возможно об этом и не подозревает? Столько геммороя ради экономии одного объекта? А потом еще проблемы с выгрузкой / загрузкой... Ну Яваскрипт позволяет кучу всего плохого сделать, но специально я бы такого точно не делал.
                  Ответить
          • if(typeof $ !== 'function') alert('A-a-a-a!');
            Ответить
            • Вы меня не понимаете... проверять по typeof наличие библиотеки, это как проверять по зеркалу надеты ли штаны на вас или нет. Ну как так может получиться, что вы в работающем сайте не уверены, а загружена ли у вас Ж-квери или нет, и что вы будете делать, если не загружена, напишете по-новой?
              Ответить
              • Это была тупая шутка.
                По делу я в принципе согласен что это левак, да и в большинстве случаев вообще сравнение с undefined ни к чему.
                Всё это в основном от недопонимания человеком того, что он делает. Ну и изредка для красоты, когда typeof проверки в линеечку стоят.)
                Ответить
        • Кстати, интересный момент:
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
            <head></head>
            <body>
              <p id="display"></p>
              <script type="text/javascript">
                (function () {
                    "use strict";
                    var object = { };
                    var display = document.getElementById("display");
                    display.innerHTML = "object.foo = " + object.foo + "<br>" +
                    "can compare to undefined? " + (object.foo === undefined) + "<br>" +
                    "can assign to undefined? " + (window.undefined = 42) + "<br>" +
                    "is reassignment successful? " + (typeof undefined);
                })();
              </script>
            </body>
          </html>

          Мозила разрешает переопределить undefined, и в последней строчке будет number. Хром не разрешает и упадет с ошибкой на предпоследней строчке. ИЕ даже ради такого дела решил поставить, восьмой, но загрузить в него локальный файл не удалось, как-то очень коряво он из под Wine работает.
          Ответить

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