Построение библиотеки JavaScript, зачем использовать ИИФЭ таким образом?
Я заметил, что многие библиотеки используют этот стиль ниже для определения своей библиотеки. Я также замечаю, что первая функция self invoking имеет какое-то отношение к системам Require.js или AMD, они всегда имеют factory в качестве аргумента, я буду больше смотреть в Require.js, всегда в Browserify.
Почему основной код, переданный в конце первой функции самозапуска в круглых скобках, является закрытием или просто считается анонимной функцией, я буду копать глубже в обоих. Каковы преимущества этого? Похоже, что внутри закрытия автор передает string
, this
и a 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, я бы с удовольствием узнал.
Ответы
Ответ 1
Этот шаблон кода называется Универсальное определение модуля (UMD). Это позволяет вам использовать вашу библиотеку JavaScript в разных средах. Он предоставляет три способа определения модулей:
IIFE имеет три параметра: globalName
, root
и factory
.
-
globalName
- это имя вашего модуля. Он применяется только к третьему способу определения модуля, т.е. Присвоению объекта модуля глобальной переменной. Например, если вы установите этот параметр на "myAwesomeModule"
и используете код в браузере (без AMD), вы можете получить доступ к своему модулю с помощью переменной myAwesomeModule
.
-
root
- это имя глобального объекта. Очевидно, что это также относится только к третьему способу определения модуля. Обычно this
передается как этот параметр, потому что this
является ссылкой на window
в браузере. Однако этот не работает в строгом режиме. Если вы хотите, чтобы ваш код работал в строгом режиме, вы можете заменить this
на typeof window !== "undefined" ? window : undefined
.
- Наконец,
factory
является анонимной функцией, которая должна возвращать ваш модуль как объект.
См. также:
Ответ 2
Это пример Универсального определения модуля (UMD). Это способ сделать JS-модуль совместимым с тремя популярными спецификациями модуля JS:
-
Определение асинхронного модуля (AMD, используемое Require.js)
define('name', [ /* dependencies */ ], factory);
-
CommonJS (экосистема Node.js)
module.exports = object;
-
Глобальный экспорт (например, на window
в браузере)
global['name'] = object;
UMD обертывает функцию factory, ответственную за создание объекта, который будет экспортироваться, и передает его в качестве аргумента непосредственно вызываемому выражению функции (IIFE), как и в фрагменте, который вы вставили. IIFE отвечает за обнаружение среды модуля и соответствующим образом экспортирует объект, созданный factory. Шаблон выглядит следующим образом:
(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
});
Многие транспилеры и инструменты сборки автоматически генерируют эту оболочку.