使用jQuery的Javascript模块模式

时间:2011-02-03 11:08:29

标签: javascript jquery design-patterns

我正在尝试掌握可插拔模块的概念,就像jQuery使用插件一样。 我的目标是将我的模块拆分成不同的文件,并在dom准备就绪后根据jQuery正确初始化。

实施例

    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="my_library.js"></script>
    <script type="text/javascript" src="modules.js"></script>
    <!-- Could be more -->

我现在正在做的方法是在设置模块之后在jquery函数内调用MY_LIBRARY.init()。

// my_library.js
var MY_LIBRARY = {
    init: function() {
        var _self = this,
            modules = _self.modules;

        if (modules) {
            for (var i in modules){
                modules[i].init();
            }
        }
    },
    modules: {}
}

// modules.js
MY_LIBRARY.modules.MyModule1 = {

    init: function(){
        // initialize stuff
        return this;
    }

};

MY_LIBRARY.modules.MyModule2 = {

    init: function(){
        // initialize stuff
        return this;
    }

};

$(function(){
    MY_LIBRARY.init();
});

问题是如何在dom准备就绪时自行调用MY_LIBRARY和模块,而不使用:

$(function(){
    MY_LIBRARY.init();
});

更新

我一直在努力解决这个问题,尝试复制jquery这样做的方式,所以我做了this piece of code。而不是使用'$',我使用'X $'作为我的自定义全局对象,所以我可以做类似的事情:

X$( 'MyModule1', { init: function(){}, doStuff: function(){} });

X$('MyModule1').doStuff();

我认为这种模式适合我。 目前,我唯一无法复制的是使用类似的东西:

X$.core.myCoreFunction() { return true; }; // plugin function yay!

X$.myCoreFunction(); // alerts X$.myCoreFunction is not a function

由于jQuery使用插件执行此操作,这有点奇怪。 对此有何看法?

1 个答案:

答案 0 :(得分:2)

我尝试在模块定义周围使用函数包装器,特别是因为除了init函数之外,您可能会发现模块之间存在很多共性。

例如,我在这里定义了一个lib函数,它可以帮助您声明一个新库,并自动将init函数绑定到document.ready

function lib(module) {
  $(function() {
    if (module.init) {
      module.init();
    }
  });

  return module;
}

var MYLIB = lib(function() {
   return {
     init: function() {
       // ...
     }
   };
}());

您可以在同一模式上使用其他变体,但它将使您无需添加大量额外代码,并允许您以相同方式管理所有库。例如,你可以让lib在最初调用时返回一个虚拟对象,在document.ready之后它应用传入的函数来生成真实对象,这样可以避免显式完全init

function lib(moduleMaker) {
  var module = {};
  $(function() {
    moduleMaker(module);
  });
  return module;
}

var MYLIB = lib(function(mylib) {
   mylib.foo = function() {/*...*/};
   // other init stuff, we've already waited for document.ready
});