13

我读过关于揭示模块模式的文章,我很喜欢它。但是对于“主对象”具有数十个子对象甚至数百个功能的大型项目呢?我不想成为将所有代码放在一个匿名函数闭包中的人。

那么大型模块模式项目是如何管理的呢?

4

2 回答 2

12

您可以使用扩充将模块分离到不同的文件中。准备好发布生产版本后,您可以将这些文件连接成一个或多个文件。

File1 定义模块 Mn

var M = M || {};
M.n = M.n || {};

(function (self) {
    self.doSomething = function () {
        console.log("something");
    };
})(M.n);

File2 定义模块 Mnp

var M = M || {};
M.n = M.n || {};
M.n.p = M.n.p || {};

(function (self) {
    self.doSomethingElse = function () {
       console.log("something else");
    };
})(M.n.p);

现在在您的“主”脚本中,您可以自由使用这些模块的成员。

M.n.doSomething();
M.n.p.doSomethingElse();

定义模块可能有点乏味,但你应该能够创造一些东西来自动化它。过去,我使用这个小脚本来帮助简化它,但您可以自己制作。您甚至可以使用一致的文件命名来进行依赖管理。

 var namespace = function(path, context, args) {
  var finalLink = namespace._generateChain(path, window);
  context.apply(finalLink, [finalLink].concat(args));
 };

 namespace._generateChain = function(path, root) {
  var segments = path.split('.'),
      cursor = root,
      segment;

  for (var i = 0; i < segments.length; ++i) {
   segment = segments[i];
   cursor = cursor[segment] = cursor[segment] || {};
  }

  return cursor;
 };

要使用:

namespace("M.n.p", function (self) {
   self.doSomethingElse = function () {
      console.log("something else");
   };
});

如果出于某种原因你想在不同的别名下包含一个变量,你可以将它传递给命名空间函数,它将作为参数传递给函数。

namespace("M.n.p", function (self, $) {
   self.doSomethingElse = function () {
      $("p").text("something else");
   };
}, jQuery);
于 2011-05-22T02:17:47.500 回答
3

使用RequireJS来组织事物。对于共享逻辑,共享方法必须存储在全局可访问的命名空间中,或通过 require() 访问。我不喜欢对应用程序代码进行许多 require() 调用,因此我将模块包含在块中,并且每个模块都通过定义包含附加到特定的命名空间。

//Core.js
define(function(){
  return {
    ns: 'global namespace'
  };
});

//newMethod.js
define(['core'], function( ns ){
  ns.newMethod = function(){ console.log( 'my new method ' ); }
});

//Application code
require(['newMethod'], function( namespace ) {
   console.log( namespace.ns ); //global namespace
   namespace.newMethod(); //'my new method'
});
于 2011-05-22T03:01:46.540 回答