Создавая библиотеку JavaScript, зачем использовать IIFE таким образом?
Я заметил, что многие библиотеки используют этот стиль ниже, чтобы определить свою библиотеку. Я также заметил, что первая самозапускающаяся функция имеет какое-то отношение к системам Require.js или AMD, в качестве аргумента у них всегда есть фабрика, я подробнее расскажу о Require.js, всегда в Browserify.
Почему основной код передается в конец первой самопризывающей функции в скобках, является ли это закрытием или просто считается анонимной функцией, я углублюсь в обе. Каковы преимущества этого? Похоже, что в закрытии автор передает string
, this
и callback
,
Это даст моей библиотеке чистый безопасный способ глобализации основного объекта в этом примере ниже Please
?
(function( globalName, root, factory ) {
if ( typeof define === 'function' && define.amd ) {
define( [], factory );
}
else if ( typeof exports === 'object' ) {
module.exports = factory();
}
else{
root[globalName] = factory();
}
}('Please', this, function(){
Я пытаюсь действительно глубоко вникнуть в JavaScript и создать свою собственную маленькую архитектуру MVC, я не хочу слышать, что я глуп или это было сделано раньше, я хочу испытать себя и учиться.
Если есть какие-то большие ресурсы для создания библиотеки JavaScript или даже лучше библиотеки MVC, я бы хотел знать.
2 ответа
Этот шаблон кода называется универсальным определением модуля (UMD). Это позволяет вам сделать вашу библиотеку JavaScript пригодной для использования в разных средах. Он предоставляет три способа определения модулей:
Определение асинхронного модуля (AMD), реализованное RequireJS и Dojo Toolkit.
define( [], factory );
CommonJS - NodeJS модули.
module.exports = factory();
Присвоение модуля глобальному объекту, например
window
в браузерах.root[globalName] = factory();
IIFE имеет три параметра: globalName
, root
а также factory
,
globalName
это имя вашего модуля. Это применимо только к третьему способу определения модуля, то есть назначению объекта вашего модуля глобальной переменной. Например, если вы установите этот параметр в"myAwesomeModule"
и использовать код в браузере (без AMD), вы можете получить доступ к вашему модулю, используяmyAwesomeModule
переменная.root
это имя глобального объекта. Очевидно, это также относится только к третьему способу определения модуля. Обычноthis
передается как этот параметр, потому чтоthis
это ссылка наwindow
в браузере. Тем не менее, это не работает в строгом режиме. Если вы хотите, чтобы ваш код работал в строгом режиме, вы можете заменитьthis
сtypeof window !== "undefined" ? window : undefined
,- В заключение,
factory
это анонимная функция, которая должна возвращать ваш модуль как объект
Смотрите также:
Это пример определения универсального модуля (UMD). Это метод, позволяющий сделать модуль JS совместимым с тремя популярными спецификациями модуля JS:
Определение асинхронного модуля (AMD, используется Require.js)
define('name', [ /* dependencies */ ], factory);
CommonJS (экосистема Node.js)
module.exports = object;
Глобальный экспорт (например, на
window
в браузере)global['name'] = object;
UMD оборачивает фабричную функцию, отвечающую за создание объекта, подлежащего экспорту, и передает его в качестве аргумента в выражение немедленно вызываемой функции (IIFE), как в вставленном вами фрагменте. IIFE отвечает за обнаружение среды модуля и экспорт объекта, созданного фабрикой соответствующим образом. Шаблон выглядит следующим образом:
(function (name, root, factory) {
// detect the module environment and
// export the result of factory()
})('name', this, function () {
// module code
// return the object to be exported
});
Многие транспортеры и инструменты сборки генерируют эту оболочку автоматически.