我注意到很多图书馆都使用这种风格来定义他们的图书馆。我还注意到第一个自我调用函数与Require.js或AMD系统有关,它们总是将工厂作为参数,我将更多地看待Require.js,总是进入Browserify。
为什么主代码在括号内传递到第一个自调用函数的末尾,这是一个闭包,或者只是被认为是一个匿名函数,我将深入研究两者。这有什么好处?看起来在封闭内部,作者传递了string
,this
和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库,我很想知道。
答案 0 :(得分:11)
此代码模式称为Universal Module Definition(UMD)。它允许您使JavaScript库在不同的环境中可用。它提供了三种定义模块的方法:
Asynchronous Module Definition(AMD),由RequireJS和Dojo Toolkit实施。
define( [], factory );
CommonJS - NodeJS模块。
module.exports = factory();
将模块分配给全局对象,例如浏览器中的window
。
root[globalName] = factory();
IIFE有三个参数:globalName
,root
和factory
。
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模块规范兼容的技术:
Asynchronous Module Definition(AMD,由Require.js使用)
define('name', [ /* dependencies */ ], factory);
CommonJS(Node.js生态系统)
module.exports = object;
全局导出(例如,在浏览器中的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
});
许多转发器和构建工具会自动生成此包装器。