把我的javascript分解成模块,我这样做了吗?

时间:2012-06-26 23:19:17

标签: javascript jquery

我正在使用javascript模块模式,到目前为止还有这个:

var APP;
if(APP == undefined) {
  APP = {};
}

APP = (function() {
    var userId = -1;
    var privateVar = '';

    var _init = function($userId) {
       userId = $userId;
    };
    var _publicMethod = function($id){
        privateVar = id;
    };
    return {
        init = function($userId) {
             _init($userId);
         },
        publicMethod = function($id) {
           _publicMethod($id);
        }
    };
})();

然后我有一个共同的utils模块:

APP.utils = (function(){

})();

然后每页我计划有一个模块,所以我不会在这些DOM元素没有事件的页面上无理由地连接事件(按钮点击等):

APP.homePage = (function(){
     return {

     };
})();

因此每个模块都有一个init()方法,我将在页面上调用它来运行必须运行的东西(例如,连接事件,设置变量,比如说userId等):

$(document).ready(function() {
   APP.init(<%= user.id %>);
   APP.homePage.init('abc');
});

所以现在如果文件太大,我也可以将它们分成单独的文件。

  1. 如果一个模块需要调用另一个模块怎么办?我想这个工作的唯一方法就是通过public api做到这一点? 例如如果homePage需要userId,我应该在homePage #init方法中传递它吗?

  2. 我的编码风格如何,任何明显的风格都不是最佳实践?

  3. 对此方法有何评论?一般来说好吗?

2 个答案:

答案 0 :(得分:2)

  

如果一个模块需要调用另一个模块怎么办?我想这个工作的唯一方法就是通过public api做到这一点?

  

e.g。如果homePage需要userId,我应该在homePage #init方法中传递它吗?

没有。我不会在所有模块中重复userId代码,而是在默认模块中为它提供一个公共getter。

  

有关编码的任何评论

此代码

var APP;
if(APP == undefined) {
  APP = {};
}

APP = ...

没用。您无需在此检查是否存在对象,因为无论如何都要覆盖它。这也意味着必须首先执行此代码。如果要使模块独立于加载顺序,则需要使用类似

的内容
var APP = (function(a) {
    var private_vars; // ...
    a.init = ...
    a.publicMethod = ... // add them to the object instead of creating new one
    a.getPrivate = function() {
        return private_vars;
    };
    return a;
})(APP || {}); // create one iff not already existing

// other file:
var APP = APP || {};
APP.utils = ... // add object to namespace

代码

var _publicMethod = function($id){
    privateVar = id;
};

看起来有点奇怪。首先,下划线通常表示对象的半私有(公共但不使用)属性,不应用于变量名称。这不是这里的情况,因为该函数将作为APP的“publicmethod”属性公开。如果需要,可以在那里使用下划线。其次,这里不需要使用函数表达式。代码位于模块的本地范围内,并且使用函数声明既可以在该范围内的任何位置使用,也可以命名该函数。你应该使用

function publicMethod($id) {
    privateVar = id;
}
a.publicMethod = publicMethod;

答案 1 :(得分:1)

在我看来,模块模式是组织代码的一种非常好的方式。回答你的问题:

1)是的,您的模块只能访问已返回的对象中公开的其他模块的方法和属性。

2)我认为你的编码风格看起来很不错。我会做出这些改变:

APP = (function() {
    var _userId = -1;
    var _privateVar = '';

    var init = function($userId) {
       _userId = $userId;
    };
    var publicMethod = function($id){
        _privateVar = id;
    };
    return {
        init : init,
        publicMethod : _publicMethod
    };
})();

首先,下划线通常用于表示“私有”属性或方法。其次,您可以取消返回对象中的额外函数,并直接指向您关注的方法或属性。这通常被称为“显示模块模式”,因为即使公共方法也没有在返回的对象中定义 - 它们只是被引用。

3)这种方法绝对是封装代码的好方法。您可以获得私有和特权方法的好处,并且通常最终得到一个更好的API,因为您只暴露需要公开的东西。

干得好。