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

时间:2016-01-19 00:24:02

标签: javascript model-view-controller umd

我注意到很多图书馆都使用这种风格来定义他们的图书馆。我还注意到第一个自我调用函数与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库,我很想知道。

2 个答案:

答案 0 :(得分:11)

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

  1. Asynchronous Module Definition(AMD),由RequireJSDojo Toolkit实施。

    define( [], factory );

  2. CommonJS - NodeJS模块。

    module.exports = factory();

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

    root[globalName] = factory();

  4. IIFE有三个参数:globalNamerootfactory

    • globalName是您模块的名称。它仅适用于定义模块的第三种方式,即将模块对象分配给全局变量。例如,如果将此参数设置为"myAwesomeModule"并使用浏览器中的代码(不使用AMD),则可以使用myAwesomeModule变量访问模块。
    • root是全局对象的名称。显然,它也仅适用于定义模块的第三种方式。通常this作为此参数传递,因为this是对浏览器中window的引用。但是,这doesn't work in strict mode。如果您希望代码在严格模式下运行,则可以将this替换为typeof window !== "undefined" ? window : undefined
    • 最后,factory是一个匿名函数,它应该将您的模块作为对象返回。

    另见:

答案 1 :(得分:10)

这是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;
    
  4. 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
    });
    

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