导出模块模式

时间:2014-11-25 18:16:34

标签: javascript module-pattern

我刚刚开始在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;
}());

1 个答案:

答案 0 :(得分:8)

TL; DR: JavaScript模块加载在不同的环境中(不同的模块加载系统,或根本没有适当的模块系统)。您拥有的代码是一些样板代码,可以让您以干净的方式正确地在这些不同的环境中加载模块。

更详细地说:您给出的实际定义是"工厂函数":在评估时返回模块内容的函数。工厂功能是一种非常灵活的功能,可以通过多种方式使用。

浏览器全局

这基本上是你的第三个例子。这里,工厂函数立即执行,并分配给全局变量:

var MyModule = (function () {
    // this is the factory function
})(); // execute immediately

结果是其他模块可以使用全局变量引用此模块 - 但这意味着您必须小心以正确的顺序加载所有模块。

异步模块定义

异步模块定义语法是一种非常简单的语法,它提供了一个名为define()spec here)的函数。这使您可以通过提供依赖项和工厂函数来描述模块:

define('module-name', ['dep1', 'dep2'], function (dep1, dep2) {
    ...
});

所以这里定义了module-name,但只有在加载所有依赖项时才会执行工厂函数 - 这意味着您可以按任何顺序加载模块定义,并且模块加载器负责执行他们都很合适。

CommonJS的

在CommonJS环境中(例如在命令行或服务器上运行的Node.js),有一个名为module的全局(-ish)对象。您分配给module.exports的任何内容都被视为模块的值。

如果你想将它与工厂函数一起使用,它与浏览器全局方案非常相似,只需将它分配给module.exports

module.exports = (function () {
    // this is the factory function
})(); // execute immediately

选项(d):以上所有

通过检查环境(例如typeof definetypeof module),可以检测哪些模块加载器可用。

顶部的代码块检测哪个模块加载器可用,并使用AMD,CommonJS或浏览器全局变量的工厂函数,具体取决于哪个。

虽然理论上你可以在你的代码中内联这些内容,但将它分离到顶部是很好的和整洁的。