首先,我为无知而道歉。我非常喜欢JavaScript,主要来自Java背景,所以这对我来说很新。我读了几篇文章,老实说,我不确定要问一个好问题。
我一直在关注“单页Web应用程序:JavaScript端到端”,现在我回过头来看一下代码并尝试重构/重构它,这对我来说很有意义。
我想了解的一件事是如何使用作者引用的模块化模式正确组织代码。
spa.model = (function () {
var people,
stateMap = { id : 1 };
people = (function () {
var methods1, method2;
method1 = function(){ … }; // do something
method2 = function(){ … }; // do something
return {
method1 : method1,
method2 : method2
};
}());
return {
people : people
};
}());
这允许我打电话 spa.model.people.method1();
我喜欢做的事情是以某种方式将people var移动到另一个文件,以便它看起来像这样
spa.model = (function () {
var people = spa.model.people,
stateMap = { id : 1 };
return {
people : people
};
}());
spa.model.people = (function () {
var method, method2;
method1 = function() { return stateMap.id; },
method2 = ... ;
return {
method1 : method1,
method2 : method2
};
}());
然而,当我像这样重构代码时,我得到各种范围错误。例如,我不能再从spa.model.people引用stateMap。
使用此模式时,如何组织更大的文件?即使只有两个对象(人和聊天),作者的spa.model文件也变得相当大。想象一下,有20个数据库对象可以建模。那将是一个巨大的档案。
答案 0 :(得分:2)
IMO,最好的方法是创建父(“模型”)和从属模块,如model.people,model.auth和model.chat。父(“模型”)管理和协调共享状态和配置。下级模块(model.people,model.auth,model.chat)不应该相互调用或以其他方式依赖于其他模块。
这是一个示例,其中模型协调3个从属模块接口(model.people,model.chat,model.auth)并在其stateMap中存储共享状态。认识到每个从属模块都有自己的封装stateMap,不会污染父状态。虽然这个例子肯定不完整,但希望它有助于指明方向。
model = (function () {
var
__undef,
configMap = {};
stateMap = {
user_id : __undef,
chatee_id : __undef
},
logIn, addPerson, rmPerson, callPerson, hangUp;
logIn = function ( user_name, passwd_str ) {
user_id = model.auth( user_name, passwd_str );
if ( user_id ) {
model.people.addPerson( user_id ):
model.chat.announceUser( user_id );
stateMap.user_id = user_id;
}
};
// ... and more methods that coordinate subordinate modules
return {
logIn : logIn,
addPerson : addPerson,
rmPerson : rmPerson,
callPerson : callPerson,
hangUp : hangUp
};
}());
这个东西并不总是那么简单。我尽量不要对组织过于笼罩,但要牢记这一点。这有点像项目管理:我见过的唯一“完美”项目计划是在项目完成后编写的。代码组织也是如此。在我的第一次通过中,我允许自己有点草率。例如,我可能会违反no-peer-talk-talk规则作为快速破解 - 但我会添加一个很大的TODO以确保它不会生成代码。
一旦我们的代码得到解决,我就给它另一个传递并清理松散的目标 - 就像前面提到的大胖子TODO一样。结果通常是组织良好,易于理解和可维护的代码。如果没有,我会冲洗并重复。
我希望有所帮助!
答案 1 :(得分:1)
我喜欢宣布我的对象有点不同。也许你可以这样做:
(function () {
spa.model = {
stateMap: {
id: 1
},
};
var people = {
method1: function() {
return stateMap.id;
},
method2: function(){},
};
spa.model.people = people;
// obviously expose spa at the end.
window.spa = spa;
}());