Должны ли новые функции jQuery быть помещены в пространство имен jQuery? - PullRequest
1 голос
/ 01 ноября 2009

Контекст: HTML-виджеты, созданные с использованием Django ModelForm и шаблона, jQuery 1.3.2, JavaScript на IE8, Firefox 3.5 или Safari 4. Процедуры: обычная функция JavaScript с некоторым количеством jQuery внутри, или jQuery Enlightenment Коди Линдли, «Добавление новых функций в пространство имен jQuery», с. 116.

У меня есть конструкция jQuery, которая повторяется несколько раз с разными переменными, и поэтому я прошу превратиться в функцию. В основном некоторые виджеты должны быть включены или отключены на основе значений других виджетов. Я написал эту функцию двумя способами. Первый способ с использованием кода jQuery внутри обычной функции JavaScript заключается в следующем:

function enable_or_disable_by_selection(master_id, master_id_value, dependent_ids) {
    /*
     * The master_id argument is the id attribute string of the master select element in the form
     * "#id_select_element_name".
     * The master_id_value argument is the selection value, a string, that causes the dependent
     * elements to be enabled when it is selected. In all other cases, they are disabled.
     * The dependent_ids argument is an array of dependent id attribute strings, such as
     * ["#id_element_1", "#id_element_2", "#id_element_3"]
     */

    /* ON CHANGE OF master_id SELECTION ELEMENT: */
    $(master_id).change(function() {
        /* If master_id_value is chosen, enable inputs for elements in dependent_ids: */
        if ($(master_id).val() == master_id_value) {
            for (var i = 0; i < dependent_ids.length; i++) {
                $(dependent_ids[i]).removeAttr("disabled");
            }
        }
        /* Otherwise disable inputs for elements in dependent_ids: */
        else {
            for (var i = 0; i < dependent_ids.length; i++) {
                $(dependent_ids[i]).attr("disabled", true);
            }
        }
    });
}

Это работает. Второй способ, рекомендованный очень способным мистером Линдли, помещает мою новую функцию в пространство имен jQuery. Его основная рекомендуемая конструкция может быть замечена здесь . Это помогает мне «избегать создания глобального кода, который потенциально может создавать конфликты». Вот код для моей функции, следуя этим рекомендациям:

(function($){
    $.enable_or_disable_by_selection = function(master_id, master_id_value, dependent_ids){
    /*
     * The master_id argument is the id attribute string of the master select element in the form
     * "#id_select_element_name".
     * The master_id_value argument is the selection value, a string, that causes the dependent
     * elements to be enabled when it is selected. In all other cases, they are disabled.
     * The dependent_ids argument is an array of dependent id attribute strings, such as
     * ["#id_element_1", "#id_element_2", "#id_element_3"]
     */

    /* CHANGE OF master_id SELECTION ELEMENT: */
        $(master_id).change(function() {
            /* If master_id_value is chosen, enable inputs for elements in dependent_ids: */
            if ($(master_id).val() == master_id_value) {
                for (var i = 0; i < dependent_ids.length; i++) {
                    $(dependent_ids[i]).removeAttr("disabled");
                }
            }
            /* Otherwise disable inputs for elements in dependent_ids: */
            else {
                for (var i = 0; i < dependent_ids.length; i++) {
                    $(dependent_ids[i]).attr("disabled", true);
                }
            }
        });
    };
})(jQuery);

Это тоже работает. Это та же самая логика, заключенная в jQuery.

Я знаю, что jQuery использует анонимные функции и замыкания для поддержания герметичного пространства имен. Смотрите «Использование (function () {}) ()» Джона Резига, здесь . Но, изучая эти два фрагмента, мне трудно увидеть риск в первой, более простой версии. Кроме того, я не прав, думая, что этот второй метод немного медленнее? Пожалуйста, помогите мне увидеть преимущества во второй версии. Я хочу знать, почему это сделано.

Полезные замечания, не относящиеся к вопросу, всегда приветствуются.

1 Ответ

2 голосов
/ 01 ноября 2009

1 - риск в вашей первой версии связан с тем, что ваша функция является глобальной, например, какая-то другая случайная библиотека добавляется на вашу страницу, и она переопределяет вашу функцию, она будет иметь катастрофические последствия эффекты с остальной частью API вашего виджета.

Я думаю, что вы хотите создавать распространяемые виджеты, и вы должны защищать свой код, сохраняя как можно большую конфиденциальность своего библиотечного кода, и вы должны быть очень избирательными и осторожными при представлении глобальных объектов.

2 - Второй пример не более медленнее , вы просто добавляете элемент в объект jQuery, время разрешения имени свойства действительно незначительно.

Я бы порекомендовал вам прочитать о пространстве имен и дизайне библиотеки:

...