Javascript'正常'对象与模块模式
Javascript 'normal' objects vs 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
};
});
模块模式更适合整体代码组织。它允许您拥有该范围专用的数据、逻辑和函数。
在第二个示例中,getModel()
是从外部获取模型的唯一方法。在模块中声明的变量是隐藏的,除非显式公开。这可能是一件非常方便的事情。
除了稍微复杂一点之外,没有什么缺点。您只需要获得更多的组织和封装选项。
我会使用一个普通对象,直到我的模型变得足够复杂,需要更多的结构和一些私有范围。当你达到这一点时,在不破坏任何使用它的代码的情况下将它重新定义为一个揭示模块是很简单的
如果每页只使用一个实例,我认为没有必要涉及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'
在你的问题中有几个概念被混为一谈
使用您所称的"普通对象",该函数将成为构造函数,并需要新的关键字。
第二个示例在IIFE内部使用"显示模块模式"。这是模块模式最流行的变体,但不幸的是存在严重缺陷。关于差异的解释,请参阅这里的答案,关于其缺陷,请参阅此处。
现在,你的问题提出了一个错误的二分法——普通对象还是模块模式?你不必做出选择——一个普通的对象可以使用模块模式,只需将它想要保持私有的东西放在它的闭包范围内。例如,
function LoginModel(){
var _notifyListeners = function(){
// Do your stuff here
};
this.model = new MyModel();
this.getModel = function(){
_notifyListeners();
return this.model;
};
}
这是一个使用模块模式的"普通对象"的示例。您必须避免做的是揭示模块模式所做的事情——将所有放入闭包范围。你应该只把你想保密的东西放在闭包范围内。
- Javascript,访问一个主要对象模块模式中的每个对象
- 模块模式和这个
- 显示模块模式在Knockout中设置模型的新实例
- Javascript中的模块模式和揭示模块模式是否仅在创建API时有用;s
- JavaScript模块模式-如何在使用对象/函数之前激发构造函数/init函数
- TypeScript代码类似于揭示模块模式结构
- 为什么在javascript中的模块模式中实现Lazy函数时范围会发生变化
- JavaScript:模块模式差异
- 显示模块模式中的私有成员
- 如何将window.setTimeout与javascript和模块模式一起使用
- j查询模块模式未命名 |如何访问“$”
- 挖空和显示模块模式的数据绑定问题
- 传递参数时如何避免模块模式中的 getter/setter 函数
- JavaScript 模块模式给出了意想不到的结果
- 从模块模式开始
- 试图通过模块模式在DOM元素上实现change()事件
- 揭示模块模式、KnockoutJS和CoffeeScript
- 使用模块模式时访问父作用域中的变量
- 模块模式:函数未定义
- 如何用模块模式扩展javascript中的事件委派