Javascript 导出模块模式
我刚开始学习JavaScript模式,并习惯于这样编写JavaScript:Javascript 导出模块模式,javascript,module-pattern,Javascript,Module Pattern,我刚开始学习JavaScript模式,并习惯于这样编写JavaScript: (function(window){ var privateVar; var privateFunc = function(param){ //do something } return{ publicFunc: function(){ do something } }(window)); 但最近我发现一些脚本在一开始就写了这样的内容: (function (
(function(window){
var privateVar;
var privateFunc = function(param){
//do something
}
return{
publicFunc: function(){
do something
}
}(window));
但最近我发现一些脚本在一开始就写了这样的内容:
(function (root, factory) {
if ( typeof define === 'function' && define.amd ) {
define('something', factory(root));
} else if ( typeof exports === 'object' ) {
module.exports = factory(root);
} else {
root.something = factory(root);
}
})(window || this, function (root) {
var privateVar;
var privateFunc = function(param){
//do something
}
return{
publicFunc: function(){
do something
}
});
那么,这段代码一开始是什么意思?这与使用此模块导出技术有什么区别:
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
TL;DR:JavaScript模块在不同的环境中加载(不同的模块加载系统,或者根本没有合适的模块系统)。您拥有的代码是一些锅炉板代码,允许您以干净的方式在这些不同的环境中正确加载模块 更详细地说:您给出的实际定义是“工厂函数”:一个在求值时返回模块内容的函数。工厂函数是一种非常灵活的东西,可以以多种方式使用 浏览器全局 这基本上是您的第三个示例。此处,工厂函数立即执行,并分配给全局变量:
var MyModule = (function () {
// this is the factory function
})(); // execute immediately
结果是其他模块可以通过使用全局变量引用此模块,但这意味着您必须小心以正确的顺序加载所有模块
异步模块定义
异步模块定义语法是一种非常简单的语法,它提供了一个名为define()
()的函数。这使您可以通过提供模块的依赖项和工厂功能来描述模块:
define('module-name', ['dep1', 'dep2'], function (dep1, dep2) {
...
});
因此,这里定义了模块名
,但工厂函数仅在加载所有依赖项时执行-这意味着您可以按任何顺序加载模块定义,模块加载器负责正确执行它们
普通的
在CommonJS环境中(例如在命令行或服务器上运行的Node.js),有一个名为module
的全局(-ish)对象。您分配给模块.exports
的任何内容都将被视为该模块的值
如果要将其与factory函数一起使用,它与browser globals场景非常类似,只需将其分配给模块。导出:
module.exports = (function () {
// this is the factory function
})(); // execute immediately
选项(d):上述所有选项
可以通过检查环境(例如typeof define
和typeof module
)来检测哪些模块加载器可用
顶部的代码块检测哪个模块加载器可用,并使用AMD、CommonJS或browser globals的工厂功能,具体取决于哪个模块可用
虽然理论上你可以在你的代码中内联完成这项工作,但将其分离到顶部是很好的,也很简洁。Hi@cloudfeets我用另一个例子更新了这个问题,你能告诉我两者的区别吗?谢谢,我明白了。。因此,只需对可用的模块加载器进行一些检查。如果没有,模块将附加到窗口全局对象上。非常感谢你。接受。实际上值得注意的是,您的样板代码可以改进<代码>窗口| |此
在Web Worker中执行时将失败(现代浏览器中的一项功能)。我认为这个| |窗口
实际上会更好。其他一些资源:和@cloudfeet-我看到很多人们只使用这个
的地方(例如我之前评论中的链接)。这在当今所有情况下都有效吗?