我正在尝试更好地组织我的JavaScript。我的目标是拥有模块化架构,我可以分成不同的文件(sitename.js,sitename.utils.js等)。
我想知道这两种模式的优点和缺点是什么,哪一种更适合分解生活在不同文件中的模块。
PATTERN#1(模块模式)
var MODULE = (function () {
//private methods
return {
common: {
init: function() {
console.log("common.init");
}
},
users: {
init: function () {
console.log("users.init");
},
show: function () {
console.log("users.show");
}
}
}
})();
PATTERN#2(单身)
var MODULE = {
common: {
init: function() {
console.log("common.init");
}
},
users: {
init: function() {
console.log("users.init");
},
show: function() {
console.log("users.show");
}
}
};
答案 0 :(得分:8)
就个人而言,我建议扩展#1,如下所示:
var Module = (function(Module) {
// A comment
Module.variable1 = 3;
/**
* init()
*/
Module.init = function() {
console.log("init");
};
// ...
return Module;
})(Module || {});
我喜欢这种模式有几个原因。一,当所有函数都是声明而不是大哈希时,文档(特别是javadoc样式)看起来更自然。第二,如果子模块的大小增加,它可以让你将它们分成多个文件,而不需要任何重构。
例如,如果Module.Users要进入自己的文件:
var Module = Module || {};
Module.Users = (function(Users) {
/**
* init()
*/
Users.init = function() {
console.log("Module.Users.init");
};
// ...
return Users;
})(Module.Users || {});
现在“module.js”和“module.users.js”可以是单独的文件,无论加载顺序如何,它们都能正常工作。另请注意模块名称的本地范围 - 如果模块名称很长,这非常方便,因为您可以使用“MyApp.Users.EditScreen”并在模块定义范围内使用类似“ES”的变量引用它
答案 1 :(得分:2)
第一种模式允许通过闭包实现私有变量,方法等。例如:
var MODULE = (function () {
var privateStuff = 'This is private';
var doStuff = function(obj) {
console.log('Doing stuff...');
console.log(privateStuff);
};
return {
common: {
init: function() {
console.log("common.init");
doStuff(this);
}
},
users: {
init: function () {
console.log("users.init");
},
show: function () {
console.log("users.show");
}
}
}
})();
privateStuff
和doStuff
不是对象的属性,除了在返回MODULE
的函数内定义的内容之外,它不可用。因此,无法显示如何使用#2执行此操作的示例。
JS没有私有成员的概念,因此您无法通过常规对象文字来定义它们。因此,如果您需要私人物品,请选择第一个选项。但是,如果不这样做,#2就更简单了。
答案 2 :(得分:1)
您编写的代码几乎相同。但是,随着代码的发展,第一种形式更容易使用,因为它允许您添加私有变量和函数。第二种形式不支持这一点,你几乎总是最终想要第一种形式。