JavaScript降低代碼圈復雜度優(yōu)化技巧
什么是圈復雜度
圈復雜度的計算基于程序中的決策結構,如條件語句(if語句)、循環(huán)語句(for、while語句)、分支語句(switch語句)等。每當程序流程圖中增加一個決策點,圈復雜度就會增加1。圈復雜度的值越高,表示代碼的復雜性越大,代碼的可讀性、可測性和可維護性也會受到影響。
通常情況下,圈復雜度的推薦值應該在1到10之間。超過10的代碼模塊可能需要進行重構,以提高代碼的可理解性和可測試性,并降低引入錯誤的風險。

輔助工具
VScode插件Code Metrics
VScode插件Code Metrics可以幫助我們快速發(fā)現(xiàn)那些需要優(yōu)化復雜度的代碼,安裝好插件后如下圖所示,在代碼上方會出現(xiàn)對應的復雜度值,根據(jù)值的大小可以看出哪些代碼是急需優(yōu)化提升可讀性。

鼠標點擊所提示復雜度數(shù)值的地方可以看到具體是哪些代碼影響了復雜度,可以進行針對性的優(yōu)化。

eslint檢查
可以使用 eslint 幫助檢查代碼的圈復雜度,當超出了某個值就會報錯。
rules: {
complexity: [
'error',
{
max: 10
}
]
}如上面的配置就是超出了 10 就會出現(xiàn)報錯信息。
圈復雜度的常用解決方法
函數(shù)拆分和重構,單一職責
較高的圈復雜度往往意味著函數(shù)或方法內(nèi)部有過多的決策路徑。通過將復雜的函數(shù)分解成多個小而清晰的函數(shù),可以降低每個函數(shù)的圈復雜度,并使代碼更易于理解和維護。拆分函數(shù)時,可根據(jù)功能模塊或責任進行分類,確保每個函數(shù)只負責一項具體的任務。
優(yōu)化前代碼:
function handle(arr) {
// 去重
let _arr=[],_arrIds=[];
for(let i=0;i<arr.length;i++){
if(_arrIds.indexOf(arr[i].id)===-1){
_arrIds.push(arr[i].id);
_arr.push(arr[i]);
}
}
// 替換
_arr.map(item=>{
for(let key in item){
if(item[key]===''){
item[key]='--';
}
}
});
// 排序
_arr.sort((item1,item2)=>item1.id-item2.id);
return _arr;
}優(yōu)化后代碼:
function removeDuplicates(arr) {
const uniqueArr = [];
const uniqueIds = [];
for(let i = 0; i < arr.length; i++) {
if(uniqueIds.indexOf(arr[i].id) === -1) {
uniqueIds.push(arr[i].id);
uniqueArr.push(arr[i]);
}
}
return uniqueArr;
}
function replaceEmptyValues(arr) {
const processedArr = arr.map(item => {
for(let key in item) {
if(item[key] === '') {
item[key] = '--';
}
}
return item;
});
return processedArr;
}
function sortById(arr) {
const sortedArr = arr.sort((item1, item2) => item1.id - item2.id);
return sortedArr;
}
function handle(arr) {
const uniqueArr = removeDuplicates(arr);
const processedArr = replaceEmptyValues(uniqueArr);
const sortedArr = sortById(processedArr);
return sortedArr;
}以上將原始函數(shù)拆分成了三個函數(shù)。removeDuplicates 函數(shù)用于去除數(shù)組中的重復元素,replaceEmptyValues 函數(shù)用于遍歷替換空值,sortById 函數(shù)用于根據(jù) id 進行排序。每個函數(shù)都只負責一個明確的職責。
衛(wèi)語句可以減少分支
對輸入條件進行多重判斷時,使用衛(wèi)語句可以減少分支語句的使用,提高代碼的可讀性和可維護性。
// 優(yōu)化前
function calculateScore(score) {
if (score < 0) {
return "Invalid score";
} else if (score < 50) {
return "Fail";
} else if (score < 70) {
return "Pass";
} else if (score < 90) {
return "Good";
} else {
return "Excellent";
}
}
// 優(yōu)化后
function calculateScore(score) {
if (score < 0) {
return "Invalid score";
}
if (score < 50) {
return "Fail";
}
if (score < 70) {
return "Pass";
}
if (score < 90) {
return "Good";
}
return "Excellent";
}通過使用衛(wèi)語句,我們將每個條件判斷獨立出來,避免了嵌套的分支語句。這種優(yōu)化方式使得代碼更加清晰,每個條件判斷都獨立成為一個邏輯塊,并且消除了使用 else 的需要。這樣做不僅提高了代碼的可讀性,還方便了后續(xù)對每個條件判斷的修改和維護。
簡化條件表達式
有相同邏輯代碼進行條件合并輸出,減少條件判斷代碼,提升可讀性。
// 優(yōu)化前
function a (num) {
if (num === 0) {
return 0;
} else if (num === 1) {
return 1;
} else if (num === 2) {
return 2;
} else {
return 3;
}
}
// 優(yōu)化后
function a (num) {
if ([0, 1, 2].indexOf(num) > -1) {
return num;
} else {
return 3;
}
}
---
// 優(yōu)化前
function a() {
if (this.a == 0) return;
if (!this.b) return;
...
}
// 優(yōu)化后
function a() {
if (this.a == 0 || !this.b) return;
...
}
---
// 優(yōu)化前
function a (type) {
if (type === 'a') {
return 'String';
} else if (type === 'b') {
return 'Number';
} else if (type === 'c') {
return 'Object';
}
}
// 優(yōu)化后
function a (type) {
let obj = {
'a': 'String',
'b': 'Number',
'c': 'Object'
};
return obj[type];
}表達式邏輯優(yōu)化
邏輯計算也會增加圈復雜度,優(yōu)化一些結構復雜的邏輯表達式,減少不必要的邏輯判斷,也將一定程度上降低圈復雜度。
// 優(yōu)化前 a && b || a && c // 優(yōu)化后 a && (b || c)
通過多態(tài)方式替代條件式。
通過多態(tài)方式替代條件式是一種優(yōu)化技巧,多態(tài)允許我們根據(jù)不同的類型執(zhí)行不同的操作,而不需要使用復雜的條件判斷邏輯。
優(yōu)化前的代碼:
class Shape {
constructor(type) {
this.type = type;
}
calculateArea() {
if (this.type === "circle") {
// 計算圓形的面積
} else if (this.type === "rectangle") {
// 計算矩形的面積
} else if (this.type === "triangle") {
// 計算三角形的面積
}
}
}優(yōu)化后的代碼:
class Shape {
calculateArea() {
throw new Error("calculateArea() method must be implemented");
}
}
class Circle extends Shape {
calculateArea() {
// 計算圓形的面積
}
}
class Rectangle extends Shape {
calculateArea() {
// 計算矩形的面積
}
}
class Triangle extends Shape {
calculateArea() {
// 計算三角形的面積
}
}使用多態(tài)的方式,我們可以通過調(diào)用相應對象的calculateArea方法來執(zhí)行特定形狀的面積計算,而無需使用復雜的條件判斷邏輯。
替換算法,優(yōu)化復雜度
當發(fā)現(xiàn)某個算法的時間復雜度較高時,可以考慮替換為一個具有更優(yōu)時間復雜度的算法,以提高代碼的性能。
// 優(yōu)化前
function findDuplicates(nums) {
let duplicates = [];
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] === nums[j]) {
duplicates.push(nums[i]);
}
}
}
return duplicates;
}
// 優(yōu)化后
function findDuplicates(nums) {
let freq = {};
let duplicates = [];
for (let num of nums) {
if (freq[num]) {
duplicates.push(num);
} else {
freq[num] = true;
}
}
return duplicates;
}需要注意的是,優(yōu)化算法并不總是適用于所有情況。在選擇替代算法時,應該綜合考慮數(shù)據(jù)規(guī)模、特定問題的特性以及算法的復雜度等因素。
分解條件式,拆分函數(shù)
當遇到復雜的條件判斷式或函數(shù)時,可以考慮將其分解為更小的部分,以提高代碼的可讀性和維護性。
優(yōu)化前代碼:
function calculateScore(player) {
if (player.score >= 100 && player.level === "expert") {
return player.score * 2;
} else if (player.score >= 50 || player.level === "intermediate") {
return player.score * 1.5;
} else {
return player.score;
}
}優(yōu)化后代碼:
function hasHighScore(player) {
return player.score >= 100 && player.level === "expert";
}
function hasIntermediateScore(player) {
return player.score >= 50 || player.level === "intermediate";
}
function calculateScore(player) {
if (hasHighScore(player)) {
return player.score * 2;
} else if (hasIntermediateScore(player)) {
return player.score * 1.5;
} else {
return player.score;
}
}將原始的復雜條件判斷式拆分成了兩個獨立的函數(shù):hasHighScore和hasIntermediateScore。這樣calculateScore函數(shù)中的條件判斷變得更加清晰和可讀。通過分解條件式和拆分函數(shù),我們可以提高代碼的可讀性、可維護性和重用性。
減少return出現(xiàn)
當前大多數(shù)圈復雜度計算工具對return個數(shù)也進行計算,如果要針對這些工具衡量規(guī)則進行優(yōu)化,減少return語句個數(shù)也為一種方式。
// 優(yōu)化前
function a(){
const value = getSomething();
if(value) {
return true;
} else {
return false;
}
}
// 優(yōu)化后
function a() {
return getSomething();
}移除控制標記,減少變量
移除控制標記可以使代碼更加簡潔、可讀性更高,并且減少了不必要的變量使用。
優(yōu)化前的代碼:
function findFirstPositive(numbers) {
let found = false;
let firstPositive = null;
for (let num of numbers) {
if (num > 0) {
found = true;
firstPositive = num;
break;
}
}
if (found) {
return firstPositive;
} else {
return -1;
}
}優(yōu)化后的代碼:
function findFirstPositive(numbers) {
for (let num of numbers) {
if (num > 0) {
return num;
}
}
return -1;
}在優(yōu)化后的代碼中,我們直接在找到第一個正數(shù)后立即返回結果,而無需使用控制標記和額外的變量。如果遍歷完整個數(shù)組后仍未找到正數(shù),則返回-1。
最后
如果只是刻板的使用圈復雜度的算法去衡量一段代碼的清晰度,這并不可取。在重構系統(tǒng)時,我們可以使用代碼圈復雜度工具來統(tǒng)計代碼的復雜度,并對復雜度較高的代碼進行具體的場景分析。但不是說一定要將復雜度優(yōu)化到某種程度,應該根據(jù)實際的業(yè)務情況做出優(yōu)化決策。
以上就是JavaScript降低代碼圈復雜度優(yōu)化技巧的詳細內(nèi)容,更多關于JavaScript代碼圈復雜度的資料請關注腳本之家其它相關文章!
相關文章
javascript實現(xiàn)鼠標移到Image上方時顯示文字效果的方法
這篇文章主要介紹了javascript實現(xiàn)鼠標移到Image上方時顯示文字效果的方法,涉及javascript鼠標事件及圖文屬性動態(tài)設置的相關技巧,可用于為圖片增加文字提示效果,需要的朋友可以參考下2015-08-08
微信小程序?qū)崿F(xiàn)打開并下載服務器上面的pdf文件到手機
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)打開并下載服務器上面的pdf文件到手機,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09
weui中的picker使用js進行動態(tài)綁定數(shù)據(jù)問題
這篇文章主要介紹了weui中的picker使用js進行動態(tài)綁定數(shù)據(jù)問題,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11

