作者poopoo888888 (阿川)
看板Ajax
标题[心得] 离开JAVASCRIPT新手村:MODULE PATTERN
时间Mon May 5 16:41:34 2014
最近写js的一些心得
希望跟各位大大分享、讨论 谢谢大家
好读版:
http://blog.turn.tw/?p=428
-----------------------------------------
最近在开发「按赞」功能,也就是类似对商品列表「按赞」
或是「加入我的最爱」之类的功能。
(本篇不讨论server side与database实作,仅讨论client side的JavaScript)
按赞的对象是衣服,於是我先开份js档:
// clothing.js
// 我知道直接写整串程式逻辑不好,一大团难以理解
// 那我用function把各小功能包起来好了!
// 先替按钮加上click event,点了之後就送出ajax,
// 把这个衣服加入我的最爱
function setupToLikeButton(){
// some codes
$('.to_like').click(function(e){
// some codes
});
}
// 再来替已经按赞过的东西加上click event,
// 点下去就送出ajax,从我的最爱移除
function setupLikedButton(){
// some codes
$('.liked').click(function(e){
// some codes
});
}
// 大功告成,写个「初始化」功能
// 正式执行clothing.js这个伟大的模组
function registerLikeButtonEvent(){
setupToLikeButton();
setupLikedButton();
}
然後在所有需要「按赞」功能的页面,加入这些程式码:
<script src="/assets/js/jquery.js"></script>
<script src="/assets/js/clothing.js"></script>
<script type="text/javascript">
$(document).ready(function(){
registerLikeButtonEvent();
});
</script>
写完之後,再看了一眼,一股凉意上心头,觉得这些程式码真的很可悲。
* 这只是把一串js code,用function随便包一包、把功能随便分开而已
* 在所有需要「按赞功能」的页面加上一行registerLikeButtonEvent(),感觉不是模组化(
一点也不物件导向),依然停留在procedural programming(这边执行一串code、再跳过去
执行那边一串code,有bug的时候光tracing code就累死人)
* setupToLikeButton跟setupLikedButton可能会被误用。应该禁止在
registerLikeButtonEvent以外的地方执行(有点像private method)
* 多了setupToLikeButton、setupLikedButton、registerLikeButtonEvent三个global
function,感觉就是很不爽
我对这串code很不满意、觉得应该有更好的pattern。
立马上网买三本书
JavaScript 设计模式
JavaScript大全(第六版)
JavaScript:优良部分
其中「JavaScript 设计模式」果然是开卷有益。
下面就是应用Module Pattern之後的写法。
// clothing.js
// 先做出一个命名空间,让变数名称留在local
var LikeButtonModule;
LikeButtonModule = (function(){
// 提示使用者这个模组跟jQuery有相依性
if (!window.jQuery) { throw new Error("LikeButtonModule requires jQuery") }
// this line declares the module dependency and
// gives the global variable a local reference.
// 这行可以增进效能
var $ = window.jQuery;
var _setupToLikeButton = function(){
// some codes
$('.to_like').click(function(e){
// some codes
});
}// end _setupToLikeButton
var _setupLikedButton = function(){
// some codes
$('.liked').click(function(e){
// some codes
});
}// end _setupLikedButton
// the public API interface
return {
initialize: function(){
// initialization
_setupToLikeButton();
_setupLikedButton();
}
};
}());
然後在所有需要「按赞」功能的页面,加入这些程式码:
<script src="/assets/js/jquery.js"></script>
<script src="/assets/js/clothing.js"></script>
<script type="text/javascript">
$(document).ready(function(){
LikeButtonModule.initialize();
});
</script>
各位觉得,有没有比较模组化的感觉呢?
Q&A
Q1: 为什麽 setupToLikeButton函式前面多了底线?
只是命名惯例,提醒developer它有private性质。
Q2: 那setupToLikeButton为何会得到private性质?
因为它是function内的一个var,被限定在function的closure内,
所以function以外的地方不能执行它。
Q3: LikeButtonModule只有提供一个initialize函式给别人使用?这什麽烂模组?
等到「按赞系统」需要的功能更复杂、更丰富时,
可以在最後return的物件内定义模组公开API,
到时这个pattern会看起来很完整很漂亮。
Q4: 我看到一个很怪的文法 (function(){}()); 请问它是什麽?
那是JavaScript的立即函式。简单来说就是定义一个function然後马上执行它。
注意这个函式最後return一个物件,
而这个物件也就是这个模组的公开API介面。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 118.169.199.175
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/Ajax/M.1399279298.A.769.html
1F:推 tomin:推 module pattern好像也有不同的写法 05/05 21:47
3F:→ pttnews:你没爬文喔~ 你的上上篇就有啦~ 05/06 09:57
4F:推 s25g5d4:...那个 Q4 是内文 而且有解答 05/06 10:18
5F:→ dlikeayu:沙盒那个比较真的符合模组化 可以随插即用 05/08 04:34