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 (

我刚开始学习JavaScript模式,并习惯于这样编写JavaScript:

(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-我看到很多人们只使用
这个
的地方(例如我之前评论中的链接)。这在当今所有情况下都有效吗?