亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么編寫js函數來提高代碼的質量

發布時間:2022-01-10 17:55:41 來源:億速云 閱讀:128 作者:iii 欄目:編程語言

這篇文章主要介紹了怎么編寫js函數來提高代碼的質量的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇怎么編寫js函數來提高代碼的質量文章都會有所收獲,下面我們一起來看看吧。

函數是實現程序功能的最基本單位,每一個程序都是由一個個最基本的函數構成的。寫好一個函數是提高程序代碼質量最關鍵的一步。本文就函數的編寫,從函數命名,代碼分布,技巧等方面入手,談談如何寫好一個可讀性高、易維護,易測試的函數。

命名

首先從命名說起,命名是提高可讀性的***步。如何為變量和函數命名一直是開發者心中的痛點之一,對于母語非英語的我們來說,更是難上加難。下面我來說說如何為函數命名的一些想法和感受:

采用統一的命名規則

在談及如何為函數取一個準確而優雅的名字之前,首先最重要的是要有統一的命名規則。這是提高代碼可讀性的最基礎的準則。
帕斯卡命名法和駝峰命名法是目前比較流行的兩種規則,不同語言采用的規則可能不一樣,但是要記住一點:保持團隊和個人風格一致。

1、帕斯卡命名法

帕斯卡命名法簡單地說就是:多個單詞組成一個名稱時,每個單詞的首字母大寫。比如:

public void SendMessage (); public void CalculatePrice ();

在C#中,這種命名法常用于類、屬性,函數等等,在JS中,構造函數也推薦采用這種方式命名。

2、駝峰命名法

駝峰命名法和帕斯卡命名法很類似,多個單詞組成一個名稱時,***個單詞全部小寫,后面單詞首字母大寫。比如:

var sendMessage = unction () {}; var calculatePrice = function () {};

駝峰命名法一般用于字段、局部變量、函數參數等等。,在JS中,函數也常用此方法命名。

采用哪種命名規則并不絕對,最重要的是要遵守團隊約定,語言規范。

盡可能完整地描述函數所做的所有事情

有的開發者可能覺得相較于長函數名來說,短函數名看起來可能更簡潔,看起來也更舒服。但是通常來說,函數名稱越短其描述的意思越抽象。函數使用者對 函數的***印象就是函數名稱,進而了解函數的功能,我們應該盡可能地描述到函數所做的所有事情,防止使用者不知道或誤解造成潛在的錯誤。

舉個例子,假設我們做一個添加評論的功能,添加完畢后并返回評論總數量,如何命名比較合適呢?

// 描述不夠完整的函數名 var count = function addComment() {} // 描述完整的函數名 var count = function addCommentAndReturnCount() {};

這只是簡單的一個例子,實際開發中可能會遇到得更多復雜的情況,單一職責原則是我們開發函數要遵守的準則,但是有時候無法做到函數單一職責時,請記 得函數名應該盡可能地描述所有事情。當你無法命名一個函數時,應該分析一下,這個函數的編寫是否科學,有什么辦法可以去優化它。

采用準確的描述動詞

這一點對母語非英語的開發者來說應該是比較難的一點,想要提高這方面的能力,最主要的還是要提高詞匯量,多閱讀優秀代碼積累經驗。

這里簡單說說我自己的一些感想和看法:

1、不要采用太抽象廣泛的單詞

很多開發人員會采用一個比較寬泛的動詞來為函數命名,最典型的一個例子就是get這個單詞。我們平時開發中經常會通過各種不同的方式拿到數據,但是每一種方式都用get就有點太抽象了。具體如何命名,要具體分析:

(1)簡單的返回數據

Person.prototype.getFullName = function() { return this.firstName = this.lastName; }

(2)從遠程獲取數據

var fetchPersons = function () {  ...     $.ajax({  }) }

(3)從本地存儲加載數據

var loadPersons = function () {};

(4)通過計算獲取數據

var calculateTotal = function () {};

(5)從數組中查找數據

var findSth = function (arr) {};

(6)從一些數據生成或得到

var createSth = function (data) {}; var buildSth = function (data) {}; var parseSth = function(data) {};

這是一個簡單的例子,我們平時開發中遇到的情況肯定會復雜得多,關鍵還是靠單詞的積累,多閱讀優秀源碼

下面是整理的一些常用的對仗詞,大家可以參考使用

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

根據不同項目和需求制定好命名規則

這一點也是很重要的,尤其是在團隊合作中,不同的項目和需求可能導致的不同的命名規則。
比如我們通常采用的命名規則是動賓結構,也就是動詞在前,名詞災后。但是有一些項目,比如數據接口等項目中,有的團隊會采用名字在前,動詞在后的形式,例如:

public static Product[] ProductsGet(){}; public static Product[] ProductsDel(){}; public static Customer[] CustomerDel(){}; public static Customer[] CustomerDel(){};

這種的好處是看到前面的名詞,比如ProductsGet,就能很快的知道這是產品相關的數據接口。
當然這個并不是絕對的,關鍵還是要團隊共同制定和遵守同一套命名規則。

函數參數

函數使用者在調用函數時,必須嚴格遵守函數定義的參數,這對函數的易用性,可測試性等方面都是至關重要的。下面我從幾個方面來談談關于如何優化好函數參數的一些想法。

參數數量

毫無疑問,函數參數越多,函數的易用性就越差,因為使用者需要嚴格眼中參數列表依次輸入參數,如果某個參數輸錯,將導致不可意料的結果。

但是,函數參數就一定越少越好嗎?我們來看看下面的例子:

var count = 0; var unitPrice = 1.5; .... ... var calculatePrice = function () {     return count * unitPrice; }

在這個例子中,我們通過calculatePrice這個函數來計算價格,函數不接收任何參數,直接通過兩個全局變量unitPrice和 count進行計算。這種函數的定義對使用者來說非常方便,直接調用即可,不用輸入任何參數。但是這里可能會有潛在的bug:全局變量可能在其他地方被修 改成其他值了,難以進行單元測試等等問題。所以,這個函數可以傳入數量和價格信息:

var calculatePrice = function(count, unitPrice) {     return count * unitPrice; }

這種方式下,函數使用者在使用時,要傳入參數進行調用,避免了全局變量可能存在的問題。另外也降低了耦合,提高了可測試性,在測試的時候就不必依賴于全局變量。

當然,在保證函數不依賴于全局變量和測試性的情況下,函數參數還是越少越好。《代碼大全》中提出將函數的參數限制在7個以內,這個可以作為我們的參考。
有的時候,我們不可避免地要使用超過10個以上函數,在這中情況下,我們可以考慮將類似的參數構造成一個類,我們來看看一個典型的例子。

我相信大家平時一定做過這樣的功能,列表篩選,其中涉及到各種條件的篩選,排序,分頁等等功能,如果將參數一個一個地列出來必定會很長,例如:

var filterHotel = function (city, checkIn, checkOut, price, star, position, wifi, meal, sort, pageIndex) {}

這是一個篩選酒店的函數,其中的參數分別是城市,入住和退房時間,價格,***,位置,是否有wifi,是否有早餐,排序,頁碼等等,實際的情況可能會更多。在這種參數特別多的情況下,我們可以考慮將一些相似的參數提取成類出來:

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) {};

將多個參數提取成對象了,雖然對象數量增多了,但是函數參數更清晰了,調用起來也更方便了。

盡量不要使用bool類型作為參數

有的時候,我們會寫出使用bool作為參數的情況,比如:

var getProduct = function(finished) {    if(finished){    }   else{    }  } // 調用 getProduct(true);

如果沒有注釋,使用者看到這樣的代碼:getProduct(true),他肯定搞不清楚true是代表什么意思,還要去查看函數定義才能明白這個函數是如何使用的。這就意味著這個函數不夠清晰,就應該考慮去優化它。通常有兩種方式去優化它:

(1)將函數一分為二,分成兩個函數getFinishedProduct和getUnFinishedProduct
(2)將bool轉換成有意義的枚舉getProduct(ProductStatus)

不要修改輸入參數

如果輸入參數在函數內被修改了,很有可能造成潛在的bug,而且使用者不知道調用函數后居然會修改函數參數。
正確使用輸入參數的做法應該是只傳入參數用于函數調用。

如果不可避免地要修改,一定要在注釋中說明。

盡量不要使用輸出參數

使用輸出參數說明這個函數不只做了一件事情,而且使用者使用的時候可能還會感到困惑。正確的方式應該是分解函數,讓函數只做一件事。

編寫函數體

函數體就是實現函數功能的整個邏輯,是一個函數最關鍵的地方。下面我談談關于函數代碼編寫的一些個人想法。

相關操作放在一起

有的時候,我們會在一個函數內進行一系列的操作來完成一個功能,比如:

var calculateTotalPrice = function()  {    var roomCount = getRoomCount();    var mealCount = getMealCount();     var roomPrice = getRoomPrice(roomCount);    var mealPrice = getMealPrice(mealCount);    return roomPrice + mealPrice; }

這段代碼計算了房間價格和早餐價格,然后將兩者相加返回總價格。

這段代碼乍一看,沒有什么問題,但是我們分析代碼,我們先是分別獲取了房間數量和早餐數量,然后再通過房間數量和早餐數量分別計算兩者的價格。這種 情況下,房間數量和計算房間價格的代碼分散在了兩個位置,早餐價格的計算也是分散到了兩個位置。也就是兩部分相關的代碼分散在了各處,這樣閱讀起代碼來邏 輯會略顯不通,代碼組織不夠好。我們應該讓相關的語句和操作放在一起,也有利于重構代碼。我們修改如下:

var calculateTotalPrice = function()  {    var roomCount = getRoomCount();    var roomPrice = getRoomPrice(roomCount);    var mealCount = getMealCount();   var mealPrice = getMealPrice(mealCount);   return roomPrice + mealPrice; }

我們將相關的操作放在一起,這樣代碼看起來更清晰了,而且也更容易重構了。

盡量減少代碼嵌套

我們平時寫if,switch或for語句是常有的事兒,也一定寫過多層if或for語句嵌套的情況,如果代碼里的嵌套超過3層,閱讀起來就會非常困難了。我們應該盡量避免代碼嵌套多層,***不要超過2層。下面我來說說我平時一些減少嵌套的技巧或方法。

if語句嵌套的問題

多層if語句嵌套是常有的事情,有什么好的方法可以減少嵌套呢?

1、盡早終止函數或返回數據

如果符合某個條件下可以直接終止函數,則應該將這個條件放在***位。我們來看看下面的例子。

 if(condition1) {     if(condition2){         if(condition3){         }         else{             return;          }        }    else{         return;     }     } else {     return;  }

這段代碼中if語句嵌套了3層,看起來已經很復雜了,我們可以將***面的return提取到最前面去。

 if(!condition1){  return;  } if(!condition2){     return; }  if(!condition3){      return;  }  //doSth

這段代碼中,我們把condition1等于false的語句提取到前面,直接終止函數,將多層嵌套的if語句重構成只有一層if語句,代碼也更清晰了。

注意:一般情況下,我們寫if語句會將條件為true的情況寫在前面,這也比較符合我們的思維習慣。如果是多層嵌套的情況,應該優先減少if語句的嵌套

2、不適用if語句或switch語句

條件語句一般來說是不可避免的,有的時候,我們要判斷很多條件就會寫很多if-elseif語句,嵌套的話,就更加麻煩了。如果有一天增加了新需 求,我們就要去增加一個if分支語句,這樣不僅修改起來麻煩,而且容易出錯。《代碼大全》提出的表驅動法可以有效地解決if語句帶來的問題。我們來看下面 這個例子:

if(condition == “case1”){     return 1;  }  elseif(condition == “case2”){      return 2;  } elseif(condition == “case3”){      return 3;  }  elseif(condition == “case4”){      return 4;  }

這段代碼分別依次判斷了四種情況,如果再增加一種情況,我們就要再新增一個if分支,這樣就可能造成潛在的問題,如何去優化這段代碼呢?我們可以采用一個Map或Dictionary來將每一種情況和相應值一一對應。

var map = {   "case1":1,   "case2":2,   "case3":3,   "case4":4 } return map[condition];

通過map優化后,整個代碼不僅更加簡潔,修改起來也更方便而且不易出錯了。

當然,很多時候我們的條件判斷語句并不是這么簡單的,可能會涉及到復雜的邏輯運算,大家可以查看《代碼大全》第18章,其中有詳細的介紹。

3、提取內層嵌套為一個函數進行調用

多層嵌套的時候,我們還可以將內層嵌套提取到一個新的函數中,然后調用該函數,這樣代碼也就更清晰了。

for循環嵌套優化

for循環嵌套相比于if嵌套來說更加復雜,閱讀起來會更麻煩,下面說說幾點要注意的東西:

1、最多只能兩層for循環嵌套
2、提取內層循環到新函數中
3、多層循環時,不要簡單地位索引變量命名為i,j,k等,容易造成混淆,要有具體的意思

提取復雜邏輯,語義化

有的時候,我們會寫出一些比較復雜的邏輯,閱讀代碼的人看到后可能搞不清楚要做什么,這個時候,就應該提取出這段復雜的邏輯代碼。

if (age > 18 && gender == "man") {   //doSth  }

這段代碼表示當年齡大于18并且是男性的話,可以doSth,但是還是不夠清晰,可以將其提取出來

 var canDoSth = function (age, gender){     return age > 18 && gender == "man";  } ... ... ... if(canDoSth(age, gender)){     //doSth  }

雖說多了一個函數,但是代碼更加清晰和語義化了。

關于“怎么編寫js函數來提高代碼的質量”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“怎么編寫js函數來提高代碼的質量”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

js
AI

西充县| 万山特区| 光山县| 商洛市| 万州区| 平江县| 阳信县| 化隆| 克拉玛依市| 共和县| 万州区| 成安县| 定结县| 衡水市| 驻马店市| 银川市| 读书| 翁源县| 团风县| 安多县| 长武县| 抚松县| 通辽市| 林西县| 印江| 旅游| 广西| 榕江县| 汉源县| 惠来县| 亳州市| 法库县| 习水县| 绍兴市| 清河县| 普格县| 依安县| 南丹县| 北安市| 冕宁县| 隆尧县|