摘要:獨(dú)立出來的函數(shù)更加容易被改寫,減少維護(hù)成本。例如一個分頁函數(shù),函數(shù)接受一個表示挑戰(zhàn)頁碼,在跳轉(zhuǎn)前需要判斷是否在有效的取值范圍。面向?qū)ο笤O(shè)計(jì)鼓勵將行為分布在合理數(shù)量的更小對象之中。
這是《 javaScript設(shè)計(jì)模式與開發(fā)實(shí)踐 》一書的最后一章"代碼重構(gòu)"。
以下的一些方法不是必須嚴(yán)格遵守的標(biāo)準(zhǔn),選擇實(shí)踐哪些,以及如何實(shí)現(xiàn)這都需根據(jù)情況而定(是不是有充足時間)
提煉函數(shù)如果在函數(shù)中有一段代碼可以獨(dú)立出來,那么最好把這些代碼放進(jìn)另外一個獨(dú)立的函數(shù)當(dāng)中去。好處有:
避免出現(xiàn)超大型函數(shù)。
獨(dú)立出來的函數(shù)有助于代碼復(fù)用。
獨(dú)立出來的函數(shù)更加容易被改寫,減少維護(hù)成本。
獨(dú)立出來的函數(shù)如果有一個良好的命名,本身就起到了注釋的作用。
例如一個獲取用戶信息的函數(shù),我們還需要打印用戶信息,這種情況下就可以獨(dú)立出打印信息的代碼。
var getUserInfo = function() { ajax("http://xxx/userInfo", function(data) { console.log("userId: " + data.userId); console.log("userName: " + data.userName); console.log("nickName: " + data.nickName); }); };
改寫:
var getUserInfo = function() { ajax("http://xxx/userInfo", function(data) { printUserInfo(data); }); }; var printUserInfo = function(data) { console.log("userId: " + data.userId); console.log("userName: " + data.userName); console.log("nickName: " + data.nickName); };合并重復(fù)代碼片段
如果一個函數(shù)內(nèi)有一些條件語句,而條件語句內(nèi)散布了一些重復(fù)代碼,就有必要進(jìn)行合并去重工作。
例如一個分頁函數(shù)paging,函數(shù)接受一個currpage表示挑戰(zhàn)頁碼,在跳轉(zhuǎn)前需要判斷currpage是否在有效的取值范圍。
var paging = function(currpage) { if (currpage <= 0) { currpage = 0; jump(currpage); // 跳轉(zhuǎn) } else if (currpage >= totalPage) { // 總頁數(shù)totalPage currpage = totalPage; jump(currpage); // 跳轉(zhuǎn) } else { jump(currpage); // 跳轉(zhuǎn) } }
負(fù)責(zé)跳轉(zhuǎn)的jump(currpage)在每個條件分支都出現(xiàn)了,所以完全把這句代碼獨(dú)立出來:
var paging = function(currpage) { if (currpage <= 0) { currpage = 0; } else if (currpage >= totalPage) { // 總頁數(shù)totalPage currpage = totalPage; } jump(currpage); // 跳轉(zhuǎn) }把條件語句提煉成函數(shù)
在程序設(shè)計(jì)中,復(fù)雜的條件語句是導(dǎo)致程序難以閱讀和理解的重要原因,而且容易增大函數(shù)代碼量。例如以一個計(jì)算商品價格的getPrice函數(shù),商品計(jì)算有個規(guī)則,夏天商品以8折出售。
var getPrice = function(price) { var date = new Date; if (date.getMonth() >= 6 && date.getMonth() <= 9 ) { // 處于夏天 return price * 0.8 } return price; }
其中的條件語句if (date.getMonth() >= 6 && date.getMonth() <= 9 )
如果改寫提煉成一個獨(dú)立的函數(shù),既能更準(zhǔn)確的表達(dá)代碼的意思,函數(shù)名又能起到注釋作用。
var isSummer = function() { var dateMonth = (new Date).getMonth(); return dateMonth >= 6 && dateMonth <= 9 ; }; var getPrice = function(price) { var date = new Date; if ( isSummer() ) { // 處于夏天 return price * 0.8 } return price; };合理使用循環(huán)
在函數(shù)體內(nèi),如果有些代碼是負(fù)責(zé)一些重復(fù)性的工作,那么合理使用循環(huán)不僅可以完成同樣的功能,還可以使代碼量更少,有一段創(chuàng)建XHR對象的代碼,為了簡化代碼,只檢測IE9已下的瀏覽器。
var creatXHR = function() { var xhr; try{ xhr = new ActiveXObject("MSXML2.XMLHTTP.6.0"); } catch(e) { try{ xhr = new ActiveXObject("MSXML2.XMLHTTP.3.0"); } catch(e) { xhr = new ActiveXObject("MSXML2.XMLHTTP"); } } return xhr; }; var xhr = creatXHR();
下面靈活的使用循環(huán),可以得到上面代碼一樣的效果:
var creatXHR = function() { var versions = ["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP"]; for (var i = 0;i < versions.length; i++) { try{ return new ActiveObject( version[i] ); }catch(e) { } } }; var xhr = creatXHR();提前讓函數(shù)退出嵌套條件分支
初學(xué)者可能有這樣一個觀念:”每個函數(shù)只能有一個入口和一個出口。”現(xiàn)代編程語言都會限制函數(shù)有一個入口。但是關(guān)于”函數(shù)只有一個出口”,往往有不一樣的看法。
下面是一個遵守“函數(shù)只有一個出口”的代碼。
var del = fucntion(obj) { var ret; if (!obj.isReadOnly) { // 不為只讀才能刪除 if (obj.isFolder) { // 判斷文件夾 ret = deletFolder(obj); } else if (obj.isFile) { // 判斷文件 ret = deletFile(obj); } } return ret; }
嵌套的條件分支語句是代碼維護(hù)者的噩夢,如果對函數(shù)的剩余部分不感興趣,那就應(yīng)該立即退出。
我們可以挑選一些條件分支,在進(jìn)入這些條件分支后,就立即讓函數(shù)退出。有一個常見的技巧。在面對一個嵌套的if分支時,我們可以把外層if表達(dá)式進(jìn)行反轉(zhuǎn)。例如:
var del = function(obj) { if (obj.isReadOnly) { // 反轉(zhuǎn)表達(dá)式 return; } if (obj.isFolder) { return deletFolder(obj); } if (obj.isFile) { return deletFile(obj); } }傳遞對象參數(shù)代替過長的參數(shù)列表
函數(shù)可能接受多個參數(shù),參數(shù)越多函數(shù)就越難理解和使用。
setUserInfo(1111, "sven", "hangzhou", "male", "137*****") // 可改寫成 setUserInfo({ id: 1111, name: "sven", address: "hangzhou", sex: "male", mobile: "137*****" })
改寫后可以不再關(guān)心參數(shù)的數(shù)量和順序,一般參數(shù)控制在4個以內(nèi),超過4個就需要轉(zhuǎn)化成對象形式。
合理使用鏈?zhǔn)秸{(diào)用鏈?zhǔn)秸{(diào)用在調(diào)試的時候非常不方便,如果一條調(diào)用鏈中有錯誤出現(xiàn),必須要把這條調(diào)用鏈拆開才能定位錯誤出現(xiàn)的地方。
如果該鏈條的結(jié)構(gòu)穩(wěn)定,后期不易發(fā)生修改,使用鏈?zhǔn)秸{(diào)用無可厚非,但是如果該鏈條容易發(fā)生變化,導(dǎo)致調(diào)試和維護(hù)困難,那么普通調(diào)用形式為佳。
分解大型類如果一個類的方法足夠復(fù)雜和龐大,那么它完全有必要作為一個多帶帶的類存在。面向?qū)ο笤O(shè)計(jì)鼓勵將行為分布在合理數(shù)量的更小對象之中。
用return退出多重循環(huán)在函數(shù)有兩重循環(huán)語句時,我們往往需要在內(nèi)層循環(huán)中判斷,當(dāng)達(dá)到臨界條件時退出外層循環(huán),有以下實(shí)現(xiàn)方式。
設(shè)置flag。
var func = function() { var flage = false; for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (i * j > 30) { flag = true; break; } } if (flag === true) { break; } } }
設(shè)置循環(huán)標(biāo)記
var func = function() { outerloop: for(var i = 0; i < 10; i++) { innerloop: for(var j = 0; j < 10; j++) { if (i * j >30) { break outerloop; } } } }
這兩種做法都讓人頭暈?zāi)垦#唵蔚淖龇ㄊ侵苯咏K止整個方法:
var func = function() { for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (i * j > 30) { return; } } } }
用return直接退出有一個問題,在循環(huán)之后如果還有代碼就無法執(zhí)行:
var func = function() { for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (i * j > 30) { return; } } } console.log(i); // 無法執(zhí)行 }
我們可以把循環(huán)后需要的代碼放到return后面,如果代碼較多,可以提煉成一個多帶帶的函數(shù)。
var print = function(i) { console.log(i); }; var func = function() { for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (i * j > 30) { return print(i); } } } };
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91730.html
摘要:比如程序會被分解為解析語法分析將詞法單元流轉(zhuǎn)換成一個由元素逐級嵌套所組成的代表了程序語法接口的書,又稱抽象語法樹。代碼生成將抽象語法樹轉(zhuǎn)換為機(jī)器能夠識別的指令。 showImg(https://segmentfault.com/img/remote/1460000009682106?w=640&h=280); 本文首發(fā)在我的個人博客:http://muyunyun.cn/ 《你不知道的...
摘要:難怪超過三分之一的開發(fā)人員工作需要一些知識。但是隨著行業(yè)的飽和,初中級前端就業(yè)形勢不容樂觀。整個系列的文章大概有篇左右,從我是如何成為一個前端工程師,到各種前端框架的知識。 為什么 call 比 apply 快? 這是一個非常有意思的問題。 作者會在參數(shù)為3個(包含3)以內(nèi)時,優(yōu)先使用 call 方法進(jìn)行事件的處理。而當(dāng)參數(shù)過多(多余3個)時,才考慮使用 apply 方法。 這個的原因...
摘要:難怪超過三分之一的開發(fā)人員工作需要一些知識。但是隨著行業(yè)的飽和,初中級前端就業(yè)形勢不容樂觀。整個系列的文章大概有篇左右,從我是如何成為一個前端工程師,到各種前端框架的知識。 為什么 call 比 apply 快? 這是一個非常有意思的問題。 作者會在參數(shù)為3個(包含3)以內(nèi)時,優(yōu)先使用 call 方法進(jìn)行事件的處理。而當(dāng)參數(shù)過多(多余3個)時,才考慮使用 apply 方法。 這個的原因...
摘要:除此以外,讓元素脫離文檔流也是一個很好的方法。因?yàn)樵匾坏┟撾x文檔流,它對其他元素的影響幾乎為零,性能的損耗就能夠有效局限于一個較小的范圍。講完重排與重繪,往元素上綁定事件也是引起性能問題的元兇。高性能這本書非常精致,內(nèi)容也非常豐富。 showImg(https://segmentfault.com/img/bVJgbt?w=600&h=784); 入手《高性能JavaScript》一...
摘要:設(shè)計(jì)模式與開發(fā)實(shí)踐讀書筆記最近利用碎片時間在上面閱讀設(shè)計(jì)模式與開發(fā)實(shí)踐讀書這本書,剛開始閱讀前兩章內(nèi)容,和大家分享下我覺得可以在項(xiàng)目中用的上的一些筆記。事件綁定暫時這么多,以后會不定期更新一些關(guān)于我讀這本書的筆記內(nèi)容 JavaScript 設(shè)計(jì)模式與開發(fā)實(shí)踐讀書筆記 最近利用碎片時間在 Kindle 上面閱讀《JavaScript 設(shè)計(jì)模式與開發(fā)實(shí)踐讀書》這本書,剛開始閱讀前兩章內(nèi)容,...
閱讀 3714·2021-11-23 09:51
閱讀 1372·2021-11-10 14:35
閱讀 4012·2021-09-22 15:01
閱讀 1285·2021-08-19 11:12
閱讀 384·2019-08-30 15:53
閱讀 1695·2019-08-29 13:04
閱讀 3434·2019-08-29 12:52
閱讀 3060·2019-08-23 16:14