4

在如下所示的简单 UMD 设置中,在哪里/如何定义rootfactory定义?

(function (root, factory) {

    // environment detection here
    console.log(root);
    console.log(factory);

}(this, function (b) {

    // module definition here

}));

我参加 UMD 聚会迟到了,所以如果这是一个愚蠢的问题,请原谅我......但是如果我运行上面的代码,我看到root返回窗口对象,并factory返回一个函数。那么第一个参数(在这种情况下是根)总是定义为窗口对象吗?第二个呢?他们是否实现了相同的跨浏览器?我正在高低搜索规范或参考来支持它,但找不到...有很多关于 UMD 奇迹的博客文章,但我找不到任何关于它如何神奇地工作的解释.

有人对它的工作原理或原因有一个简单的解释吗?

4

2 回答 2

9

这是一个 IIFE(立即调用的函数表达式),这里有很好的解释。

简而言之,您正在创建一个仅调用一次的函数,并且您将两个参数传递给它,this并且function(b). 这两个参数被命名rootfactory在 IIFE 体内。

好处是 IIFE 的主体在“私人范围”内独立运作。它之外的变量名无效,并且您没有冲突问题。

现在,回到你的问题,你是this作为一个论点传递的。这是全局对象。在浏览器中它是window,在 Node 中它是global. 在 IIFE 中的这两种情况下,您都将其称为root并且在您的模块中称为b. 不管你怎么称呼它,另一个优点是你的 minifier 可以在c不破坏你的代码的情况下把它捡起来并翻译成其他东西。这与正常情况相反,其中windowdocument任何模块名称都无法缩小。

您还传递了一个名为 factory 的函数。这是你的模块。如果没有 AMD 或 CommonJS,您通常会这样做:

(function (root, factory) {
    root.myModuleName = factory(root);  
}(this, function (b) {
    // module definition here
}));

这将创建您的模块并将其附加到全局对象,以便您可以使用它。工厂方法中只有一个参数,通常需要传递全局对象。您还可以使用更多参数来传递任何模块依赖项:

(function (root, c, factory) {
    root.myModuleName = factory(root, c);  
}(this, jQuery, function (b, $) {
    // module definition here
    // You refer to jQuery as $ without having to call noConflict
}));
于 2016-07-14T08:16:57.650 回答
6

不总是。root可以global在 Node 中,也可以在浏览器中window。它通过提供来传递thisfactory是参数后面this的函数b。这就是应用程序代码(“业务逻辑”或“肉”)所在的位置。

UMD 应该可以在任何 JavaScript 环境中工作,它只是针对存在的模块加载系统调整逻辑。

于 2015-09-18T19:03:03.933 回答