目前,我正在开发一个大型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
};
});
答案 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所做的事情 - 将所有内容放入闭包范围。你应该只将你想要保密的东西放在封闭范围内。