Javascript'普通'对象与模块模式

时间:2014-05-01 08:09:48

标签: javascript object-literal module-pattern

目前,我正在开发一个大型Javascript应用程序(单页),并且我已经在网上搜索了一些最佳实践。大多数项目使用模块模式,因此对象不会污染全局命名空间。此刻我使用普通对象:

function LoginModel(){
    this.model = new MyModel();

    this.getModel = function(){
        return this.model;
    };
}

这是可读且易于维护的(我的观点)。仅仅因为命名空间而使用模块模式是否更好,或者它是否具有我不知道的其他优点(计数器内存泄漏,...)?此外,我已经将文件拆分为具有良好的MVC模式并在需要时销毁每个对象(计数器内存泄漏)。所以主要的问题是:在我的情况下,我是否需要使用模块模式?

模块模式:

var LoginModel = (function(){
   var model = MyModel;

   function getModel(){
      return model;
   };

   return {
      getModel: getModel
   };
});

3 个答案:

答案 0 :(得分:3)

模块模式更适合整体代码组织。它允许您拥有该范围内的数据,逻辑和函数。

在您的第二个示例中,getModel()是从外部获取模型的唯一方式。除非明确公开,否则隐藏在模块中声明的变量。这可能是一件非常方便的事情。

除了稍微复杂一点之外,并没有任何缺点。您只需获得更多组织和封装选项。

我使用普通对象,直到我的模型变得足够复杂,需要更多结构和一些私有范围。当你达到这一点时,重新定义它作为一个揭示模块是毫不费力的,而不会破坏任何使用它的代码。

答案 1 :(得分:2)

如果您每页只使用一个实例,我认为不需要涉及new关键字。所以我个人会像你在上一个例子中那样创建一个揭示模块,然后使用" public"属性。

虽然我没有看到getModel()函数的观点,但MyModel显然可以在范围之外访问。

我会稍微改写一下:

var LoginModel = (function(model, window, undefined){

    function init(){ } // or whatever

    function doSomethingWithModel(){
        console.log(model);
    }

    return { init: init };

})(MyModel, window);

如果您不确定哪些模块会获得model,您可以使用宽松的扩充和更改

})(MyModel, window);

})(MyModel || {}, window);

如果您需要多个模块实例,它将如下所示:

var LoginModel = (function(model, window, undefined){

    function loginModel(name){ // constructor
        this.name = name; // something instance specific
    }

    loginModel.prototype.getName = function(){
        return this.name;
    };

    return loginModel;

})(MyModel, window);

var lm1 = new LoginModel('foo');
var lm2 = new LoginModel('bar');

console.log(lm1.getName(), lm2.getName()); // 'foo', 'bar'

答案 2 :(得分:1)

你的问题中有几个概念混淆了

使用你所谓的"普通对象",该函数成为构造函数,需要new关键字。

第二个例子使用IIFE内部的Revealing Module Pattern。这是模块模式中最流行的变体,但遗憾的是存在严重缺陷。有关差异的解释,请参阅我的回答here,并了解其缺陷,请参阅here

现在,你的问题构成了错误的二分法 - 正常的对象或模块模式?您不必做出选择 - 普通对象可以使用模块模式,只需将其想要保密的内容放在其封闭范围内即可。例如,

function LoginModel(){
    var _notifyListeners = function(){ 
        // Do your stuff here
    };

    this.model = new MyModel();

    this.getModel = function(){
        _notifyListeners();
        return this.model;
    };
}

这是"普通对象的一个​​例子"使用模块模式。您必须避免做的是Revealing Module Pattern所做的事情 - 将所有内容放入闭包范围。你应该只将你想要保密的东西放在封闭范围内。