前端代码质量
如何使前端代码变得可维护可读, 如何量化定义代码的复杂度
现状
- 团队代码风格不一致,无法进行整体质量把控
- 没办法量化代码复杂度
圈复杂度
定义
圈复杂度用来衡量一个模块判定结构的复杂程度,数量上表现为线性无关的路径条数,即合理的预防错误所需测试的最少路径条数。圈复杂度大说明程序代码可能质量低且难于测试和维护,根据经验,程序的可能错误和高的圈复杂度有着很大关系。
衡量标准
计算方法
采用判定节点数
+1
- 判断
if - elseswitch - case- 一个
case数量+1 - 三元
- 循环
for- 条件
&&||
function getComplexity(value) {
let result = 1;
if (value < 0) {
result--;
}
for (let i = 0; i < 10; i++) {
result += Math.random();
}
switch (+result) {
case 1:
result += 20;
break;
case 2:
result += 30;
break;
default:
result += 10;
break;
}
return result > 20 ? result : result;
}
complexity = 1(if) + 1(for) + 2(case) + 1(三目) + 1 = 6
点边计算
E: 控制流图中边的数量N: 控制流中点的数量P: 独立组件数量
降低圈复杂度
抽象配置
- 优化前
function doSomething(payload) {
if (payload.type === "EAT") {
eat(payload.value);
} else if (payload.type === "WRITE") {
write(payload.value);
} else if (payload.type === "SING") {
sing(payload.type);
}
}
// 圈复杂度 4
- 优化后
const ACTIONS = {
"EAT": eat,
"WRITE": write,
"SING": sing
};
function doSomething(payload) {
ACTIONS[payload.type](payload.value);
}
// 圈复杂度 1
提炼函数
一个功能函数只做一件事
- 优化前
function doSomething(v, u) {
if (v < u) {
v = v + u;
u = v - u;
v = v - u;
}
doOther(v, u);
}
- 优化后
const getOrdered(v, u) {
if (v < u) {
v = v + u;
u = v - u;
v = v - u;
}
return [v, u];
}
function doSomething(v, u) {
([v, u] = getOrdered(v, u))
doOther(v, u);
}
判断条件简化和提取
重判断提取使用
Array.includes()
- 优化前
function check(name) {
if (name === "wuw" || name === "polm") {
console.log("good");
}
}
- 优化后
const NAMES = ["wuw", "polm"];
function checkout(name) {
if (NAMES.includes(name)) {
console.log("good")
}
}
使用return和break代替标记位
- 优化前
function doSomething() {
let flag = false;
for (let i = 0, len = arr.length; i < len; i++) {
if (arr[i].isNew) {
flag = false;
}
}
!flag && doSomething()
}
filter(Boolean)技巧
-
优化前

-
优化后

includes优化()
如果你怕 includes 的兼容性不佳,可以改成 [89,91,92].indexOf(this.appId) >= 0
-
优化前

-
优化后
