Может ли подключаемый модуль jQuery быть локальным для модуля?

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

Если я определяю расширение/плагин jQuery ВНУТРИ модуля, будет ли оно локальным для этого модуля, как и другие функции? (Подозреваю, что нет...)

Пример:

var igPartListManager = (function () {
    // Define a jQuery plug-in I'd like to be local to igPartListManager 
    (function ($) {
        $.fn.myExtension = function () {
            // Do something with this.each()...
        }
    })(jQuery);

    var doSomethingCore = function () {
        // Use my jQuery plug-in
        $("selector").myExtension();
    };

    return {
        doSomething
            : doSomethingCore
    };
})();

Будет ли это успешным вне igPartListManager?

...
$("some_unrelated_selector").myExtension();

Если это так, как мне лучше всего инкапсулировать «локальные» функции jQuery-extension/plug-in внутри модуля?


person n8wrl    schedule 31.12.2013    source источник
comment
переменные являются локальными для области видимости, а не модулей, но в данном случае плагин jQuery — это функция, а функция создает новую область видимости, так что да! Однако $ является глобальным, поэтому при использовании правильных кавычек в селекторе плагин работает.   -  person adeneo    schedule 31.12.2013


Ответы (1)


Чтобы лучше объяснить это, я сделал небольшой пример того, что на самом деле происходит, когда вы определяете свое расширение:

(function ($) {
    // $ = window.jQuery;
    $.fn.myExtension = function () {
        // Do something with this.each()...
    }
})(window.jQuery); // Note window.jQuery is basically the same as just jQuery from your example code

Всякий раз, когда вы пытаетесь получить доступ к переменной, движок javascript всплывает во всех инкапсулирующих областях вплоть до области window. Первая область, в которой есть эта переменная, — это область, которая используется. Поскольку в вашем случае область окна содержит вашу переменную jQuery, вы можете назвать ее «глобальной».

При вызове этого $("some_unrelated_selector).myExtension(); движок ищет переменную $. Если в этот момент эта переменная указывает на window.jQuery, вы фактически используете тот же объект, что и раньше. Так что да, в этом случае это удалось бы. Но только если вы выполнили функцию igPartListManager перед попыткой вызвать $().myExtension();.

Единственный способ создать локальную область для ваших расширений — глубоко скопировать переменную window.jQuery в локальную переменную перед добавлением к ней расширений.

Пример: объект глубокого копирования JavaScript

person Hless    schedule 31.12.2013
comment
Спасибо @Hless. Я переосмысливаю свои требования здесь, потому что я не уверен, что буду использовать расширение jQuery в моем модуле достаточно, чтобы оправдать мою собственную «глубокую копию» jQuery. Большое спасибо! - person n8wrl; 31.12.2013
comment
Да, я думаю, что добавление функций к $.fn глобального объекта — это ваш лучший выбор на данный момент. Класс jQuery становится тяжелее, но я не думаю, что полная копия этого класса принесет вам пользу с точки зрения производительности. Это практически то же самое, что загружать исходный код jQuery несколько раз, используя каждый раз разные имена переменных. - person Hless; 31.12.2013
comment
И все же функции, которые мне нужны, являются ЛОКАЛЬНЫМИ для моего модуля, поэтому добавление их в глобальный $.fn — это утечка, которую я не хочу. Эти функции больше никому не нужны. - person n8wrl; 31.12.2013