Создавая библиотеку 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 пригодной для использования в разных средах. Он предоставляет три способа определения модулей:

  1. Определение асинхронного модуля (AMD), реализованное RequireJS и Dojo Toolkit.

    define( [], factory );

  2. CommonJS - NodeJS модули.

    module.exports = factory();

  3. Присвоение модуля глобальному объекту, например 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:

  1. Определение асинхронного модуля (AMD, используется Require.js)

    define('name', [ /* dependencies */ ], factory);
    
  2. CommonJS (экосистема Node.js)

    module.exports = object;
    
  3. Глобальный экспорт (например, на 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
});

Многие транспортеры и инструменты сборки генерируют эту оболочку автоматически.

Другие вопросы по тегам