寫js也有那麼段時間了,也看過幾本關於js的書,從最初的《鋒利的jquery》《高性能javasrcipt》到《javascript設計模式》等,雖然看了些書,看到了書中的各類理論與技巧,然而在實際的使用中,真正用到的倒是很少。javascript
js的面向對象與我所熟悉的c#等語言的面向對象稍有不一樣,但基本都會有封裝,繼承,多態等。弱語言天生就具有多態性,沒有類型檢測的js相對而言能夠作出許多強類型語言所作不到的靈活,雖然這不能說徹底沒有壞處,但這個優點讓js代碼變得豐富多彩。java
程序的編寫基本遵照一些原則,好比單一原則,開閉原則,迪米特原則等,js的也不例外。然而由於js的特殊性,不少時候隨着需求的改變及代碼量的增長頗有可能會變成麪條式的代碼,變的難以閱讀,不易擴展,重複而且分散。這時候就不由的想要改變,想要重構。jquery
亡羊補牢,猶未爲晚。c#
重構的目的是讓程序更加健壯,即健壯性。符合基本原則,可擴展,可複用,易維護等。設計模式
那麼怎樣重構才能讓程序更加健壯呢?隔離變化,抽象不變。讓程序更符合基本原則。閉包
var outConding=function(result){ var outCond=1; var outConded=2; kinds={ kindItem:outCond, KindChildren:outConded }; cols=[{ value:outCond }]; }; var inConding=function(result){ var inCond=1; var inConded=2; kinds={ kind:inCond, Children:inConded }; cols=[{ price:inConded, value:inCond },{
price:inConded,
value:inCond
}];
}
outConding(res);
inConding(res);
上面代碼是否健壯呢?很明顯至少沒有考慮到複用性及擴張性,若是以後須要添加onCoding,offCoding難道還須要將重複的代碼在一次次寫一遍嗎?函數
那麼這就須要完善了,對其重構。兩段代碼有明顯的類似的地方,好比結構,擁有kinds,cols等。但也有不一樣的地方,好比臨時參數。如何將其抽離出來以符合健壯性呢?性能
var conding=function(result){ kinds={}, cols=[]; }
首先將不變的抽象出來,只留下基本結構。而後分析變化。問題來了,裏面須要依賴臨時變量,臨時變量的變量名是未知的,數量是未知的,這該如何抽象出來呢?this
用重載能夠嗎?不行,變量在不變的程序裏是未知的。那讓不變的程序繼承變化的父類呢?。。。好像能夠,那來實現試試吧。spa
js有原型鏈能夠模擬繼承,讓父類變的可變化,子類繼承父類,子類中使用的變量在父類中聲明,這就能夠解決變量的未知性了。
寫着寫着,突然有個想法,不是有個更簡單的方法嗎?既然是弱語言爲什麼必定要用強語言的優點放棄本身的?
var conding=function(tempParams, kindsParam,colsParam, result){ var CondingParams=new tempParams(); kinds=kindsParam(CondingParams), cols=colsParam(CondingParams); };
js沒有類型檢測,那麼我傳個參數表示臨時變量集合能夠嗎?固然能夠。接下來就是可擴展,遵循單一職責原則,開閉原則,迪米特原則,完成如下代碼。
var conding=function(tempParams, kindsParam,colsParam, result){ var CondingParams=new tempParams(); kinds=kindsParam(CondingParams), cols=colsParam(CondingParams); }; var outCondingInfo = { tempParams: function () { this.outCond = 1; this.outConded = 2; }, kindsParam: function (param) { return { kindItem: param.outCond, KindChildren: param.outConded } }, colsParam: function (param) { return [{ value: param.outCond }] } } var inCondingInfo = { tempParams: function () { this.inCond = 1; this.inConded = 2; }, kindsParam:function(param){ return { kind:param.inCond, Children:param.inConded } } , colsParam: function (param) { return [{ price: param.inConded, value: param.inCond }, { price: param.inConded, value: param.inCond }]; } } var res=1; conding(outCondingInfo.tempParams,outCondingInfo.kindsParam,outCondingInfo.colsParam,res) conding(inCondingInfo.tempParams,inCondingInfo.kindsParam,inCondingInfo.colsParam,res)
這個對於最初的代碼,若是須要新增一個onCoding,只須要新增一個onCondingInfo的對象就能夠了,是否是可擴展了?是否是相對而已面向對象了一點?
不過一味追求健壯性,面向對象,雖然不會成爲麪條式代碼,但有可能在你不講解的狀況下,他人很難看懂你寫的是什麼,因而這就形成了閱讀性,關聯上下文內容等問題。這即是取捨的問題了。
還有一些重構的小技巧,好比只在一個方法內使用,其餘地方使用不到的方法,儘可能不要單獨寫爲一個全局函數,最好是直接在使用的方法內用一個臨時變量存儲他,儘可能不去污染全局。使用閉包讓待執行的方法順序執行,或限定執行完幾個方法後在執行特定方法等。
若是有好的意見或好的技巧,歡迎分享,歡迎指點。