這篇文章主要介紹了怎么編寫js函數(shù)來提高代碼的質(zhì)量的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇怎么編寫js函數(shù)來提高代碼的質(zhì)量文章都會(huì)有所收獲,下面我們一起來看看吧。
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供碭山網(wǎng)站建設(shè)、碭山做網(wǎng)站、碭山網(wǎng)站設(shè)計(jì)、碭山網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、碭山企業(yè)網(wǎng)站模板建站服務(wù),十余年碭山做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
函數(shù)是實(shí)現(xiàn)程序功能的最基本單位,每一個(gè)程序都是由一個(gè)個(gè)最基本的函數(shù)構(gòu)成的。寫好一個(gè)函數(shù)是提高程序代碼質(zhì)量最關(guān)鍵的一步。本文就函數(shù)的編寫,從函數(shù)命名,代碼分布,技巧等方面入手,談?wù)勅绾螌懞靡粋€(gè)可讀性高、易維護(hù),易測(cè)試的函數(shù)。
命名
首先從命名說起,命名是提高可讀性的***步。如何為變量和函數(shù)命名一直是開發(fā)者心中的痛點(diǎn)之一,對(duì)于母語非英語的我們來說,更是難上加難。下面我來說說如何為函數(shù)命名的一些想法和感受:
采用統(tǒng)一的命名規(guī)則
在談及如何為函數(shù)取一個(gè)準(zhǔn)確而優(yōu)雅的名字之前,首先最重要的是要有統(tǒng)一的命名規(guī)則。這是提高代碼可讀性的最基礎(chǔ)的準(zhǔn)則。
帕斯卡命名法和駝峰命名法是目前比較流行的兩種規(guī)則,不同語言采用的規(guī)則可能不一樣,但是要記住一點(diǎn):保持團(tuán)隊(duì)和個(gè)人風(fēng)格一致。
1、帕斯卡命名法
帕斯卡命名法簡(jiǎn)單地說就是:多個(gè)單詞組成一個(gè)名稱時(shí),每個(gè)單詞的首字母大寫。比如:
public void SendMessage (); public void CalculatePrice ();
在C#中,這種命名法常用于類、屬性,函數(shù)等等,在JS中,構(gòu)造函數(shù)也推薦采用這種方式命名。
2、駝峰命名法
駝峰命名法和帕斯卡命名法很類似,多個(gè)單詞組成一個(gè)名稱時(shí),***個(gè)單詞全部小寫,后面單詞首字母大寫。比如:
var sendMessage = unction () {}; var calculatePrice = function () {};
駝峰命名法一般用于字段、局部變量、函數(shù)參數(shù)等等。,在JS中,函數(shù)也常用此方法命名。
采用哪種命名規(guī)則并不絕對(duì),最重要的是要遵守團(tuán)隊(duì)約定,語言規(guī)范。
盡可能完整地描述函數(shù)所做的所有事情
有的開發(fā)者可能覺得相較于長(zhǎng)函數(shù)名來說,短函數(shù)名看起來可能更簡(jiǎn)潔,看起來也更舒服。但是通常來說,函數(shù)名稱越短其描述的意思越抽象。函數(shù)使用者對(duì) 函數(shù)的***印象就是函數(shù)名稱,進(jìn)而了解函數(shù)的功能,我們應(yīng)該盡可能地描述到函數(shù)所做的所有事情,防止使用者不知道或誤解造成潛在的錯(cuò)誤。
舉個(gè)例子,假設(shè)我們做一個(gè)添加評(píng)論的功能,添加完畢后并返回評(píng)論總數(shù)量,如何命名比較合適呢?
// 描述不夠完整的函數(shù)名 var count = function addComment() {} // 描述完整的函數(shù)名 var count = function addCommentAndReturnCount() {};
這只是簡(jiǎn)單的一個(gè)例子,實(shí)際開發(fā)中可能會(huì)遇到得更多復(fù)雜的情況,單一職責(zé)原則是我們開發(fā)函數(shù)要遵守的準(zhǔn)則,但是有時(shí)候無法做到函數(shù)單一職責(zé)時(shí),請(qǐng)記 得函數(shù)名應(yīng)該盡可能地描述所有事情。當(dāng)你無法命名一個(gè)函數(shù)時(shí),應(yīng)該分析一下,這個(gè)函數(shù)的編寫是否科學(xué),有什么辦法可以去優(yōu)化它。
采用準(zhǔn)確的描述動(dòng)詞
這一點(diǎn)對(duì)母語非英語的開發(fā)者來說應(yīng)該是比較難的一點(diǎn),想要提高這方面的能力,最主要的還是要提高詞匯量,多閱讀優(yōu)秀代碼積累經(jīng)驗(yàn)。
這里簡(jiǎn)單說說我自己的一些感想和看法:
1、不要采用太抽象廣泛的單詞
很多開發(fā)人員會(huì)采用一個(gè)比較寬泛的動(dòng)詞來為函數(shù)命名,最典型的一個(gè)例子就是get這個(gè)單詞。我們平時(shí)開發(fā)中經(jīng)常會(huì)通過各種不同的方式拿到數(shù)據(jù),但是每一種方式都用get就有點(diǎn)太抽象了。具體如何命名,要具體分析:
(1)簡(jiǎn)單的返回?cái)?shù)據(jù)
Person.prototype.getFullName = function() { return this.firstName = this.lastName; }
(2)從遠(yuǎn)程獲取數(shù)據(jù)
var fetchPersons = function () { ... $.ajax({ }) }
(3)從本地存儲(chǔ)加載數(shù)據(jù)
var loadPersons = function () {};
(4)通過計(jì)算獲取數(shù)據(jù)
var calculateTotal = function () {};
(5)從數(shù)組中查找數(shù)據(jù)
var findSth = function (arr) {};
(6)從一些數(shù)據(jù)生成或得到
var createSth = function (data) {}; var buildSth = function (data) {}; var parseSth = function(data) {};
這是一個(gè)簡(jiǎn)單的例子,我們平時(shí)開發(fā)中遇到的情況肯定會(huì)復(fù)雜得多,關(guān)鍵還是靠單詞的積累,多閱讀優(yōu)秀源碼
下面是整理的一些常用的對(duì)仗詞,大家可以參考使用
add/remove increment/decrement open/close begin/end insert/delete show/hide create/destory lock/unlock source/target first/last min/max star/stop get/put next/previous up/down get/set old/new
根據(jù)不同項(xiàng)目和需求制定好命名規(guī)則
這一點(diǎn)也是很重要的,尤其是在團(tuán)隊(duì)合作中,不同的項(xiàng)目和需求可能導(dǎo)致的不同的命名規(guī)則。
比如我們通常采用的命名規(guī)則是動(dòng)賓結(jié)構(gòu),也就是動(dòng)詞在前,名詞災(zāi)后。但是有一些項(xiàng)目,比如數(shù)據(jù)接口等項(xiàng)目中,有的團(tuán)隊(duì)會(huì)采用名字在前,動(dòng)詞在后的形式,例如:
public static Product[] ProductsGet(){}; public static Product[] ProductsDel(){}; public static Customer[] CustomerDel(){}; public static Customer[] CustomerDel(){};
這種的好處是看到前面的名詞,比如ProductsGet,就能很快的知道這是產(chǎn)品相關(guān)的數(shù)據(jù)接口。
當(dāng)然這個(gè)并不是絕對(duì)的,關(guān)鍵還是要團(tuán)隊(duì)共同制定和遵守同一套命名規(guī)則。
函數(shù)參數(shù)
函數(shù)使用者在調(diào)用函數(shù)時(shí),必須嚴(yán)格遵守函數(shù)定義的參數(shù),這對(duì)函數(shù)的易用性,可測(cè)試性等方面都是至關(guān)重要的。下面我從幾個(gè)方面來談?wù)勱P(guān)于如何優(yōu)化好函數(shù)參數(shù)的一些想法。
參數(shù)數(shù)量
毫無疑問,函數(shù)參數(shù)越多,函數(shù)的易用性就越差,因?yàn)槭褂谜咝枰獓?yán)格眼中參數(shù)列表依次輸入?yún)?shù),如果某個(gè)參數(shù)輸錯(cuò),將導(dǎo)致不可意料的結(jié)果。
但是,函數(shù)參數(shù)就一定越少越好嗎?我們來看看下面的例子:
var count = 0; var unitPrice = 1.5; .... ... var calculatePrice = function () { return count * unitPrice; }
在這個(gè)例子中,我們通過calculatePrice這個(gè)函數(shù)來計(jì)算價(jià)格,函數(shù)不接收任何參數(shù),直接通過兩個(gè)全局變量unitPrice和 count進(jìn)行計(jì)算。這種函數(shù)的定義對(duì)使用者來說非常方便,直接調(diào)用即可,不用輸入任何參數(shù)。但是這里可能會(huì)有潛在的bug:全局變量可能在其他地方被修 改成其他值了,難以進(jìn)行單元測(cè)試等等問題。所以,這個(gè)函數(shù)可以傳入數(shù)量和價(jià)格信息:
var calculatePrice = function(count, unitPrice) { return count * unitPrice; }
這種方式下,函數(shù)使用者在使用時(shí),要傳入?yún)?shù)進(jìn)行調(diào)用,避免了全局變量可能存在的問題。另外也降低了耦合,提高了可測(cè)試性,在測(cè)試的時(shí)候就不必依賴于全局變量。
當(dāng)然,在保證函數(shù)不依賴于全局變量和測(cè)試性的情況下,函數(shù)參數(shù)還是越少越好。《代碼大全》中提出將函數(shù)的參數(shù)限制在7個(gè)以內(nèi),這個(gè)可以作為我們的參考。
有的時(shí)候,我們不可避免地要使用超過10個(gè)以上函數(shù),在這中情況下,我們可以考慮將類似的參數(shù)構(gòu)造成一個(gè)類,我們來看看一個(gè)典型的例子。
我相信大家平時(shí)一定做過這樣的功能,列表篩選,其中涉及到各種條件的篩選,排序,分頁等等功能,如果將參數(shù)一個(gè)一個(gè)地列出來必定會(huì)很長(zhǎng),例如:
var filterHotel = function (city, checkIn, checkOut, price, star, position, wifi, meal, sort, pageIndex) {}
這是一個(gè)篩選酒店的函數(shù),其中的參數(shù)分別是城市,入住和退房時(shí)間,價(jià)格,***,位置,是否有wifi,是否有早餐,排序,頁碼等等,實(shí)際的情況可能會(huì)更多。在這種參數(shù)特別多的情況下,我們可以考慮將一些相似的參數(shù)提取成類出來:
function DatePlace (city, checkIn, checkOut){ this.city = city; this.checkIn = checkIn; this.checkOut = checkOut } function HotelFeature (price, star, position, wifi, meal){ this.price = price; this.star = star; this.position = position; this.wifi = wifi; this.meal = meal; } var filterHotel = function (datePlce, hotelFeature, sort, pageIndex) {};
將多個(gè)參數(shù)提取成對(duì)象了,雖然對(duì)象數(shù)量增多了,但是函數(shù)參數(shù)更清晰了,調(diào)用起來也更方便了。
盡量不要使用bool類型作為參數(shù)
有的時(shí)候,我們會(huì)寫出使用bool作為參數(shù)的情況,比如:
var getProduct = function(finished) { if(finished){ } else{ } } // 調(diào)用 getProduct(true);
如果沒有注釋,使用者看到這樣的代碼:getProduct(true),他肯定搞不清楚true是代表什么意思,還要去查看函數(shù)定義才能明白這個(gè)函數(shù)是如何使用的。這就意味著這個(gè)函數(shù)不夠清晰,就應(yīng)該考慮去優(yōu)化它。通常有兩種方式去優(yōu)化它:
(1)將函數(shù)一分為二,分成兩個(gè)函數(shù)getFinishedProduct和getUnFinishedProduct
(2)將bool轉(zhuǎn)換成有意義的枚舉getProduct(ProductStatus)
不要修改輸入?yún)?shù)
如果輸入?yún)?shù)在函數(shù)內(nèi)被修改了,很有可能造成潛在的bug,而且使用者不知道調(diào)用函數(shù)后居然會(huì)修改函數(shù)參數(shù)。
正確使用輸入?yún)?shù)的做法應(yīng)該是只傳入?yún)?shù)用于函數(shù)調(diào)用。
如果不可避免地要修改,一定要在注釋中說明。
盡量不要使用輸出參數(shù)
使用輸出參數(shù)說明這個(gè)函數(shù)不只做了一件事情,而且使用者使用的時(shí)候可能還會(huì)感到困惑。正確的方式應(yīng)該是分解函數(shù),讓函數(shù)只做一件事。
編寫函數(shù)體
函數(shù)體就是實(shí)現(xiàn)函數(shù)功能的整個(gè)邏輯,是一個(gè)函數(shù)最關(guān)鍵的地方。下面我談?wù)勱P(guān)于函數(shù)代碼編寫的一些個(gè)人想法。
相關(guān)操作放在一起
有的時(shí)候,我們會(huì)在一個(gè)函數(shù)內(nèi)進(jìn)行一系列的操作來完成一個(gè)功能,比如:
var calculateTotalPrice = function() { var roomCount = getRoomCount(); var mealCount = getMealCount(); var roomPrice = getRoomPrice(roomCount); var mealPrice = getMealPrice(mealCount); return roomPrice + mealPrice; }
這段代碼計(jì)算了房間價(jià)格和早餐價(jià)格,然后將兩者相加返回總價(jià)格。
這段代碼乍一看,沒有什么問題,但是我們分析代碼,我們先是分別獲取了房間數(shù)量和早餐數(shù)量,然后再通過房間數(shù)量和早餐數(shù)量分別計(jì)算兩者的價(jià)格。這種 情況下,房間數(shù)量和計(jì)算房間價(jià)格的代碼分散在了兩個(gè)位置,早餐價(jià)格的計(jì)算也是分散到了兩個(gè)位置。也就是兩部分相關(guān)的代碼分散在了各處,這樣閱讀起代碼來邏 輯會(huì)略顯不通,代碼組織不夠好。我們應(yīng)該讓相關(guān)的語句和操作放在一起,也有利于重構(gòu)代碼。我們修改如下:
var calculateTotalPrice = function() { var roomCount = getRoomCount(); var roomPrice = getRoomPrice(roomCount); var mealCount = getMealCount(); var mealPrice = getMealPrice(mealCount); return roomPrice + mealPrice; }
我們將相關(guān)的操作放在一起,這樣代碼看起來更清晰了,而且也更容易重構(gòu)了。
盡量減少代碼嵌套
我們平時(shí)寫if,switch或for語句是常有的事兒,也一定寫過多層if或for語句嵌套的情況,如果代碼里的嵌套超過3層,閱讀起來就會(huì)非常困難了。我們應(yīng)該盡量避免代碼嵌套多層,***不要超過2層。下面我來說說我平時(shí)一些減少嵌套的技巧或方法。
if語句嵌套的問題
多層if語句嵌套是常有的事情,有什么好的方法可以減少嵌套呢?
1、盡早終止函數(shù)或返回?cái)?shù)據(jù)
如果符合某個(gè)條件下可以直接終止函數(shù),則應(yīng)該將這個(gè)條件放在***位。我們來看看下面的例子。
if(condition1) { if(condition2){ if(condition3){ } else{ return; } } else{ return; } } else { return; }
這段代碼中if語句嵌套了3層,看起來已經(jīng)很復(fù)雜了,我們可以將***面的return提取到最前面去。
if(!condition1){ return; } if(!condition2){ return; } if(!condition3){ return; } //doSth
這段代碼中,我們把condition1等于false的語句提取到前面,直接終止函數(shù),將多層嵌套的if語句重構(gòu)成只有一層if語句,代碼也更清晰了。
注意:一般情況下,我們寫if語句會(huì)將條件為true的情況寫在前面,這也比較符合我們的思維習(xí)慣。如果是多層嵌套的情況,應(yīng)該優(yōu)先減少if語句的嵌套
2、不適用if語句或switch語句
條件語句一般來說是不可避免的,有的時(shí)候,我們要判斷很多條件就會(huì)寫很多if-elseif語句,嵌套的話,就更加麻煩了。如果有一天增加了新需 求,我們就要去增加一個(gè)if分支語句,這樣不僅修改起來麻煩,而且容易出錯(cuò)。《代碼大全》提出的表驅(qū)動(dòng)法可以有效地解決if語句帶來的問題。我們來看下面 這個(gè)例子:
if(condition == “case1”){ return 1; } elseif(condition == “case2”){ return 2; } elseif(condition == “case3”){ return 3; } elseif(condition == “case4”){ return 4; }
這段代碼分別依次判斷了四種情況,如果再增加一種情況,我們就要再新增一個(gè)if分支,這樣就可能造成潛在的問題,如何去優(yōu)化這段代碼呢?我們可以采用一個(gè)Map或Dictionary來將每一種情況和相應(yīng)值一一對(duì)應(yīng)。
var map = { "case1":1, "case2":2, "case3":3, "case4":4 } return map[condition];
通過map優(yōu)化后,整個(gè)代碼不僅更加簡(jiǎn)潔,修改起來也更方便而且不易出錯(cuò)了。
當(dāng)然,很多時(shí)候我們的條件判斷語句并不是這么簡(jiǎn)單的,可能會(huì)涉及到復(fù)雜的邏輯運(yùn)算,大家可以查看《代碼大全》第18章,其中有詳細(xì)的介紹。
3、提取內(nèi)層嵌套為一個(gè)函數(shù)進(jìn)行調(diào)用
多層嵌套的時(shí)候,我們還可以將內(nèi)層嵌套提取到一個(gè)新的函數(shù)中,然后調(diào)用該函數(shù),這樣代碼也就更清晰了。
for循環(huán)嵌套優(yōu)化
for循環(huán)嵌套相比于if嵌套來說更加復(fù)雜,閱讀起來會(huì)更麻煩,下面說說幾點(diǎn)要注意的東西:
1、最多只能兩層for循環(huán)嵌套
2、提取內(nèi)層循環(huán)到新函數(shù)中
3、多層循環(huán)時(shí),不要簡(jiǎn)單地位索引變量命名為i,j,k等,容易造成混淆,要有具體的意思
提取復(fù)雜邏輯,語義化
有的時(shí)候,我們會(huì)寫出一些比較復(fù)雜的邏輯,閱讀代碼的人看到后可能搞不清楚要做什么,這個(gè)時(shí)候,就應(yīng)該提取出這段復(fù)雜的邏輯代碼。
if (age > 18 && gender == "man") { //doSth }
這段代碼表示當(dāng)年齡大于18并且是男性的話,可以doSth,但是還是不夠清晰,可以將其提取出來
var canDoSth = function (age, gender){ return age > 18 && gender == "man"; } ... ... ... if(canDoSth(age, gender)){ //doSth }
雖說多了一個(gè)函數(shù),但是代碼更加清晰和語義化了。
關(guān)于“怎么編寫js函數(shù)來提高代碼的質(zhì)量”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“怎么編寫js函數(shù)來提高代碼的質(zhì)量”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
本文題目:怎么編寫js函數(shù)來提高代碼的質(zhì)量
文章轉(zhuǎn)載:http://aaarwkj.com/article2/gjdpoc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、ChatGPT、網(wǎng)站改版、網(wǎng)站導(dǎo)航、網(wǎng)站制作、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
營(yíng)銷型網(wǎng)站建設(shè)知識(shí)