17

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

为什么将主要代码传递到括号内的第一个自调用函数的末尾,这是一个闭包,还是只是一个匿名函数,我将深入研究两者。这样做有什么好处?看起来作者在闭包内部传递了 a stringthis和 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 库的资源,我很想知道。

4

2 回答 2

15

此 Code Pattern 称为通用模块定义(UMD)。它允许您使您的 JavaScript 库在不同的环境中可用。它提供了三种定义模块的方式:

  1. 异步模块定义(AMD),由RequireJSDojo Toolkit实现。

    define( [], factory );

  2. CommonJS — NodeJS 模块。

    module.exports = factory();

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

    root[globalName] = factory();

IIFE 具有三个参数globalNamerootfactory

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

也可以看看:

于 2016-01-19T00:33:52.713 回答
11

这是通用模块定义(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
});

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

于 2016-01-19T00:37:56.083 回答