Javascript UMD - где / как определены root, фабрика?
В простой настройке UMD, подобной следующей, где / как root
а также factory
определены?
(function (root, factory) {
// environment detection here
console.log(root);
console.log(factory);
}(this, function (b) {
// module definition here
}));
Я опаздываю на вечеринку UMD, так что, пожалуйста, прости меня, если это глупый вопрос... но если я запускаю приведенный выше код, я вижу root
возвращает объект окна, и factory
возвращает функцию. Так всегда ли первый аргумент (в данном случае root) определяется как объект окна? Как насчет второго? В них реализованы одинаковые кросс-браузеры? Я ищу высоко и низко для спецификации или ссылки, чтобы поддержать это и не могу найти... есть много постов в блоге о чудесах UMD, но я не могу найти никакого объяснения того, как это волшебно работает,
У кого-нибудь есть простое объяснение того, как или почему это работает?
2 ответа
Не всегда. root
может быть global
в узле или в браузере это может быть window
, Это передано, предоставляя this
, factory
это функция, которая после this
с аргументом b
, Вот где находится код приложения ("бизнес-логика" или "мясо").
UMD должен работать в любой среде JavaScript, он просто адаптирует логику к тому, что присутствует в системе загрузки модулей.
Это IIFE (выражение для немедленного вызова функции), которое хорошо объясняется здесь.
Проще говоря, вы создаете функцию, которая вызывается только один раз, и вы передаете ей два аргумента, this
а также function(b)
, Эти два аргумента названы root
а также factory
внутри тела IIFE.
Преимущество состоит в том, что тело IIFE работает изолированно, в "частном масштабе". Имена переменных вне этого не имеют никакого эффекта, и у вас нет проблем конфликта.
Теперь вернемся к вашему вопросу, вы проходите this
в качестве аргумента. Это глобальный объект. В браузере это window
и в узле это global
, В обоих случаях в IIFE вы называете это root
и в вашем модуле как b
, Как бы вы это ни называли, еще одним преимуществом является то, что ваш минификатор может взять его и перевести на c
или что-то еще, не нарушая ваш код. Это в отличие от нормальной ситуации, когда window
или же document
или любые имена модулей не могут быть уменьшены.
Вы также передаете функцию с именем factory. Это твой модуль. Без AMD или CommonJS вы обычно делаете:
(function (root, factory) {
root.myModuleName = factory(root);
}(this, function (b) {
// module definition here
}));
Это создаст ваш модуль и присоединит его к глобальному объекту, чтобы вы могли его использовать. Имея только один аргумент в методе фабрики, вам обычно нужно передать глобальный объект. Вы также можете использовать больше аргументов для передачи любых зависимостей модуля:
(function (root, c, factory) {
root.myModuleName = factory(root, c);
}(this, jQuery, function (b, $) {
// module definition here
// You refer to jQuery as $ without having to call noConflict
}));