您的位置:首页 > Web前端 > JavaScript

JavaScript代码重构系列-重新组织你的函数

2014-12-10 16:00 148 查看
原文地址:http://www.monring.com/front_end/javascript-refactor-composing-methods.html

JavaScript代码重构系列中,最重要的要算這節了: 重新组织你的函数

提炼函数

将函数内联化

用查询取代临时变量

以临时变量取代高消耗的查询

将临时变量内联化

引入解释性变量

剖解临时变量

移除对参数的赋值动作

以函数对象取代函数

替换你的算法

提炼函数

信號:你有一段代码可以被组织在一起并独立出来。

操作:将这段代码放进一个独立函数中,并让函数名称解释该函数的用途。

當你有一個很長的函數,這也是一個非常直接的重構信號,但真正能讓你用【提煉函數】方法重構代碼時候,必須發現有一段代碼可以被組織在一起,也就是說這段代碼能夠看作一個獨立的工作模塊。

将函数内联化

信號:一个函数,它本体应该与其名称同样清楚易懂。

操作:在函数调用点插入函数本体,然后移除该函数。

這條重構方法跟【提煉函數】是相對立的,如果你發現你【提煉函數】的函數它的內容跟它名字一樣清晰易懂,那麼還是把它內聯回去,讓它看上去更直接。

也有可能【提煉函數】重構完後,長函數(主函數)中添加了一些代碼,這時候被提取出來的函數寫到長函數中更直接,那我們也需要先內聯回去,然後再看它和其他代碼一起組織成新函數是否能再利用【提煉函數】。

用查询取代临时变量

信號:你的程序以一个临时变量保存某一表达式的运算结果。

操作:将这个表达式提炼到一个独立函数中。将这个临时变量的所有被引用点替换为对新函数的调用。新函数可被其他函数使用。

臨時變量一般在函數內部實用,這樣就促使你不得不讓你的函數變得更長,這樣才能使你的代碼訪問到你的臨時變量。這時候,如果將臨時變量換成一個查詢式,那麼代碼就更清晰,更簡潔了,但這個需要將高消耗的查詢除外。

用临时变量取代高消耗的查询

信號:多次調用的查詢式是一個高消耗的函數

操作:用臨時變量儲存該查詢,將該查詢式調用處用臨時變量代替

該方法與【用查询取代临时变量】是對立的,但出發點不同,本方法出發點最重要的為了提升代碼性能,一些高消耗的方法如果在函數體中多次調用,我們需要用臨時變量緩存起來。最常見的是DOM查詢式,高循環運算的函數查詢式。

将临时变量内联化

信號:你有一个临时变量,只被一个简单表达式赋值一次,而它妨碍了其他重构手法。

操作:将所有对该变量的引用动作,替换为对它赋值的那个表达式本身。

本方法多半是作为【用查询取代临时变量】的一部分来使用,所以真正的动机出现在后者那儿。惟一单独使用本方法的情况是:你发现某个临时变量被赋予某个函数调用的返回值。一般来说,这样的临时变量不会有任何危害,你可以放心地把它留在那儿。但如果这个临时变量妨碍了其他的重构方法(例如【提取函數】),你就应该将它內聯化。

引入解释性变量

信號:你有一个复杂的表达式。

操作:将该表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途。

【引入解釋性變量】能使方法體看上去更加易懂。特別是當表達式特別複雜的情況下,更能體現該方法的優勢。該方法非常有用,但很多時候我們都實用【提取函數】的方法來重構,畢竟臨時變量只對當前函數體有效,所以只有當局部變量令【提取函數】難以進行,我們才實用【引入解釋性變量】方法來處理重構。

剖解临时变量

信號:你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不是一个集用临时变量(collecting temporary variable)。

操作:针对每次赋值,创造一个独立的、对应的临时变量。

除了循環變量和集用臨時變量這兩種臨時變量被多次賦值的情況,其他被多次賦值的臨時變量都在敲醒我們重構的警鐘。每個臨時變量應該只承擔一個單獨的責任,例如【用临时变量取代高消耗的查询】中生成的臨時變量,如果賦值多次,就應該重構以多個臨時代替。

移除对参数的赋值动作

信號:你的代码对一个参数进行赋值动作。

操作:以一个临时变量取代该参数的位置,以函數返回值在原函數改變對象。

在JavaScript中非常特別的一個地方,但一個對象作為參數傳遞時,傳遞的往往是一個原始的引用,甚至都不是副本。這樣出現的問題就是,參數被修改後會引起原函數中的對象會相應被修改,引起很多混雜不清晰的現象,甚至會是錯誤。所以如果參數是一個值類型,可以以一个临时变量取代该参数的位置。如果參數為一個引用類型,這時就需要避免這種情況出現。

以函数对象取代函数

信號:你有一个大型函数,其中对局部变量的使用,使你无法釆用【提取函數】。

操作:将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的值域(field) 然后你可以在同一个对象中将这个大型函数分解为数个小型函数。

如果一個大型函數,功能比較單一,且局部變量很多,這時候我們沒辦法採用單純的【提取函數】方法來重構,這個時候我們就可以把大型函數轉換成一個函數對象來處理,然後將函數體分解成小函數。

替换你的算法

信號:把某个算法替换为另一个更清晰的算法。

操作:将函数本体(method body)替换为另一个算法。

算法過於複雜,或則循環過於深入都是影響代碼閱讀的因素,這裡我們需要了解循环复杂度。可以用【提取函數】或替換算法來解決這類複雜問題。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: