构建一个 JavaScript 库,为什么要这样使用 IIFE?

Building a JavaScript library, why use an IIFE this way?

我注意到很多图书馆都使用下面的这种风格来定义他们的图书馆。我还注意到第一个自调用函数与 Require.js 或 AMD 系统有关,它们总是将工厂作为参数,我将更多地研究 Require.js,一直研究 Browserify。

为什么主要代码传递到括号内的第一个自调用函数的末尾,这是一个闭包,还是只是一个匿名函数,我将深入研究两者。这有什么好处?看起来作者在闭包内部传递了 stringthiscallback

这是否会为我的库提供一种干净安全的方式来全球化下面这个示例中的主要对象 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 库的资源,我很想知道。

此代码模式称为 Universal Module Definition (UMD)。它允许您使 JavaScript 库可用于不同的环境。它提供了三种定义模块的方式:

  1. Asynchronous Module Definition (AMD), implemented by RequireJS and Dojo Toolkit.

    define( [], factory );

  2. CommonJS — NodeJS 模块。

    module.exports = factory();

  3. 将模块分配给全局对象,例如在浏览器中window

    root[globalName] = factory();

IIFE 有三个参数:globalNamerootfactory

  • globalName 是您的模块的名称。它仅适用于定义模块的第三种方式,即将模块对象分配给全局变量。例如,如果您将此参数设置为 "myAwesomeModule" 并在浏览器中使用代码(没有 AMD),您可以使用 myAwesomeModule 变量访问您的模块。
  • root 是全局对象的名称。显然,它也只适用于定义模块的第三种方式。通常 this 作为此参数传递,因为 this 在浏览器中是对 window 的引用。然而,这。如果你想让你的代码在严格模式下工作,你可以用 typeof window !== "undefined" ? window : undefined.
  • 替换 this
  • 最后,factory 是一个匿名函数,它应该 return 你的模块作为对象。

另请参阅:

这是Universal Module Definition (UMD) 的示例。它是一种使 JS 模块兼容三种流行的 JS 模块规范的技术:

  1. Asynchronous Module Definition(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
});

许多转译器和构建工具会自动生成此包装器。