在如下的简单UMD设置中,root
和factory
定义在哪里/如何?
(function (root, factory) {
// environment detection here
console.log(root);
console.log(factory);
}(this, function (b) {
// module definition here
}));
我迟到了UMD派对,所以如果这是一个愚蠢的问题,请原谅我...但如果我运行上面的代码,我看到root
返回窗口对象,{{1返回一个函数。那么第一个参数(在本例中为root)总是定义为窗口对象吗?那第二个怎么样?它们是否实现了相同的跨浏览器?我正在搜索高低版本的规格或参考来支持这个并且找不到...有很多关于UMD奇迹的博客文章,但是我找不到任何有关这个神奇工作原理的解释
是否有人对如何或为何如此有效有简单的解释?
答案 0 :(得分:7)
这是一个IIFE(立即调用的函数表达式),很好地解释了here。
简单地说,你创建一个只调用一次的函数,然后你传递两个参数this
和function(b)
。这两个参数在IIFE体内命名为root
和factory
。
好处是IIFE的主体在“私人范围”中孤立地工作。它之外的变量名称没有效果,你没有冲突问题。
现在,回到你的问题,你传递this
作为参数。这是全球对象。在浏览器中,它是window
,在Node中是global
。在IIFE的两种情况下,您将其称为root
,在您的模块中称为b
。无论你怎么称呼它,另一个好处是你的minifier可以把它拿起并将其翻译成c
或其他东西,而不会破坏你的代码。这与正常情况形成对比,其中window
或document
或任何模块名称无法缩小。
您还传递了一个名为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
}));
答案 1 :(得分:5)
并非总是如此。 root
在节点或浏览器中可以是global
,可以是window
。它通过提供this
来传递。 factory
是this
之后带有参数b
的函数。这就是应用程序代码(“业务逻辑”或“肉”)的所在。
UMD应该可以在任何JavaScript环境中工作,它只是适应模块加载系统所存在的逻辑。