对给定 JavaScript 代码通过复杂度分析工具分析代码的复杂度和可维护性评分。
相关文章
检测代码复杂度
功能清单
- 使用了 escomplex 模块对代码进行了复杂度分析
- 输出整体分析结果和每个函数的详细分析结果,包括逻辑行数、物理行数、圈复杂度、参数数量等。
- 输出了整体代码的可维护性评分。
一、escomplex 是什么
escomplex 是一个 JavaScript 代码复杂度分析工具,用于评估 JavaScript 代码的复杂度和可维护性。它可以分析代码的各种指标,包括逻辑行数、物理行数、圈复杂度、参数数量、代码长度、代码词汇量、代码难度、代码体积、代码工作量等。通过分析这些指标,可以帮助开发人员了解代码的复杂度情况,从而进行代码质量评估、性能优化和重构工作。
二、使用 escomplex 分析代码
1、安装 escomplex
2、进行复杂度分析
1 2
| // 使用 escomplex 分析更复杂的代码 const analysis = escomplex.analyse(code)
|
3、解析报告
三、完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| const escomplex = require('escomplex');
const code = `function removeDuplicates(dataset) { return Array.from(new Set(dataset)); // 使用 Set 去重 }
function binarySearch(dataset, target) { let left = 0; let right = dataset.length - 1; while (left <= right) { const mid = Math.floor((left + right) / 2); if (dataset[mid] === target) { return mid; // 如果找到目标值,返回索引 } else if (dataset[mid] < target) { left = mid + 1; // 如果目标值在右侧,更新左边界 } else { right = mid - 1; // 如果目标值在左侧,更新右边界 } } return -1; // 如果未找到目标值,返回 -1 }`;
const analysis = escomplex.analyse(code);
function logAggregateDetails(aggregate) { console.log(`--- 整体分析结果 ---`); console.log(`-----------------------------`); console.log(`逻辑行数: ${aggregate.sloc.logical}`); console.log(`物理行数: ${aggregate.sloc.physical}`); console.log(`圈复杂度: ${aggregate.cyclomatic}`); console.log(`参数数量: ${aggregate.params}`); console.log(`定义所在行数: ${aggregate.line}`); console.log(`-----------------------------`); console.log(`哈斯特德度量:`); console.log(` - 操作符总类: ${aggregate.halstead.operators.distinct} (总数: ${aggregate.halstead.operators.total})`); console.log(` - 操作数总类: ${aggregate.halstead.operands.distinct} (总数: ${aggregate.halstead.operands.total})`); console.log(` - 代码长度: ${aggregate.halstead.length.toFixed(2)}`); console.log(` - 代码词汇量: ${aggregate.halstead.vocabulary.toFixed(2)}`); console.log(` - 代码难度: ${aggregate.halstead.difficulty.toFixed(2)}`); console.log(` - 代码体积: ${aggregate.halstead.volume.toFixed(2)}`); console.log(` - 代码工作量: ${aggregate.halstead.effort.toFixed(2)}`); console.log(` - 可能存在的错误数量估计: ${aggregate.halstead.bugs.toFixed(2)}`); console.log(` - 编写和测试所需时间估计: ${aggregate.halstead.time.toFixed(2)}`); console.log(`-----------------------------`); console.log(`圈复杂度密度: ${aggregate.cyclomaticDensity}`); console.log(`\n`); }
function logFunctionDetails(func) { console.log(`--- 详细分析结果 ---`); console.log(`-----------------------------`); console.log(`函数名称或标识符: ${func.name}`); console.log(`-----------------------------`); console.log(`逻辑行数: ${func.sloc.logical}`); console.log(`物理行数: ${func.sloc.physical}`); console.log(`圈复杂度: ${func.cyclomatic}`); console.log(`参数数量: ${func.params}`); console.log(`定义所在行数: ${func.line}`); console.log(`-----------------------------`); console.log(`哈斯特德度量:`); console.log(` - 操作符总类: ${func.halstead.operators.distinct} (总数: ${func.halstead.operators.total})`); console.log(` - 操作数总类: ${func.halstead.operands.distinct} (总数: ${func.halstead.operands.total})`); console.log(` - 代码长度: ${func.halstead.length.toFixed(2)}`); console.log(` - 代码词汇量: ${func.halstead.vocabulary.toFixed(2)}`); console.log(` - 代码难度: ${func.halstead.difficulty.toFixed(2)}`); console.log(` - 代码体积: ${func.halstead.volume.toFixed(2)}`); console.log(` - 代码工作量: ${func.halstead.effort.toFixed(2)}`); console.log(` - 可能存在的错误数量估计: ${func.halstead.bugs.toFixed(2)}`); console.log(` - 编写和测试所需时间估计: ${func.halstead.time.toFixed(2)}`); console.log(`-----------------------------`); console.log(`圈复杂度密度: ${func.cyclomaticDensity}`); console.log(`\n`); }
logAggregateDetails(analysis.aggregate);
analysis.functions.forEach(logFunctionDetails);
console.log('\n整体可维护性评分:'); console.log(`评分: ${analysis.maintainability}`);
|
输出结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| --- 整体分析结果 --- ----------------------------- 逻辑行数: 15 物理行数: 20 圈复杂度: 4 参数数量: 3 定义所在行数: 3 ----------------------------- 哈斯特德度量: - 操作符总类: 18 (总数: 35) - 操作数总类: 16 (总数: 37) - 代码长度: 72.00 - 代码词汇量: 34.00 - 代码难度: 20.81 - 代码体积: 366.30 - 代码工作量: 7623.56 - 可能存在的错误数量估计: 0.12 - 编写和测试所需时间估计: 423.53 ----------------------------- 圈复杂度密度: 26.666666666666668
--- 详细分析结果 --- ----------------------------- 函数名称或标识符: removeDuplicates ----------------------------- 逻辑行数: 1 物理行数: 3 圈复杂度: 1 参数数量: 1 定义所在行数: 3 ----------------------------- 哈斯特德度量: - 操作符总类: 4 (总数: 4) - 操作数总类: 4 (总数: 5) - 代码长度: 9.00 - 代码词汇量: 8.00 - 代码难度: 2.50 - 代码体积: 27.00 - 代码工作量: 67.50 - 可能存在的错误数量估计: 0.01 - 编写和测试所需时间估计: 3.75 ----------------------------- 圈复杂度密度: 100
--- 详细分析结果 --- ----------------------------- 函数名称或标识符: binarySearch ----------------------------- 逻辑行数: 12 物理行数: 15 圈复杂度: 4 参数数量: 2 定义所在行数: 8 ----------------------------- 哈斯特德度量: - 操作符总类: 16 (总数: 29) - 操作数总类: 11 (总数: 30) - 代码长度: 59.00 - 代码词汇量: 27.00 - 代码难度: 21.82 - 代码体积: 280.54 - 代码工作量: 6120.84 - 可能存在的错误数量估计: 0.09 - 编写和测试所需时间估计: 340.05 ----------------------------- 圈复杂度密度: 33.33333333333333
整体可维护性评分: 评分: 112.9785791088806
|