Index

complexity

强制执行程序中允许的最大圈复杂度

圈复杂度衡量程序源代码中线性独立路径的数量。此规则允许设置圈复杂度阈值。

🌐 Cyclomatic complexity measures the number of linearly independent paths through a program’s source code. This rule allows setting a cyclomatic complexity threshold.

function a(x) {
    if (true) {
        return x; // 1st path
    } else if (false) {
        return x+1; // 2nd path
    } else {
        return 4; // 3rd path
    }
}

规则详情

🌐 Rule Details

此规则旨在通过限制程序允许的圈复杂度来减少代码复杂性。因此,当圈复杂度超过配置阈值(默认值为20)时,它会发出警告。

🌐 This rule is aimed at reducing code complexity by capping the amount of cyclomatic complexity allowed in a program. As such, it will warn when the cyclomatic complexity crosses the configured threshold (default is 20).

不正确代码的示例,最多为 2

🌐 Examples of incorrect code for a maximum of 2:

在线运行
/*eslint complexity: ["error", 2]*/

function a(x) {
    if (true) {
        return x;
    } else if (false) {
        return x+1;
    } else {
        return 4; // 3rd path
    }
}

function b() {
    foo ||= 1;
    bar &&= 1;
}

function c(a = {}) { // default parameter -> 2nd path
    const { b = 'default' } = a; // default value during destructuring -> 3rd path
}

function d(a) {
    return a?.b?.c; // optional chaining with two optional properties creates two additional branches
}

最大为 2正确代码示例:

🌐 Examples of correct code for a maximum of 2:

在线运行
/*eslint complexity: ["error", 2]*/

function a(x) {
    if (true) {
        return x;
    } else {
        return 4;
    }
}

function b() {
    foo ||= 1;
}

类字段初始化器和类静态块是隐式函数。因此,它们的复杂度是为每个初始化器和每个静态块单独计算的,并且不会对包含它们的代码的复杂度产生影响。

🌐 Class field initializers and class static blocks are implicit functions. Therefore, their complexity is calculated separately for each initializer and each static block, and it doesn’t contribute to the complexity of the enclosing code.

额外的 错误 代码示例,最多为 2

🌐 Examples of additional incorrect code for a maximum of 2:

在线运行
/*eslint complexity: ["error", 2]*/

class C {
    x = a || b || c; // this initializer has complexity = 3
}

class D { // this static block has complexity = 3
    static {
        if (foo) {
            bar = baz || qux;
        }
    }
}

最多 2 的其他 正确 代码示例:

🌐 Examples of additional correct code for a maximum of 2:

在线运行
/*eslint complexity: ["error", 2]*/

function foo() { // this function has complexity = 1
    class C {
        x = a + b; // this initializer has complexity = 1
        y = c || d; // this initializer has complexity = 2
        z = e && f; // this initializer has complexity = 2

        static p = g || h; // this initializer has complexity = 2
        static q = i ? j : k; // this initializer has complexity = 2

        static { // this static block has complexity = 2
            if (foo) {
                baz = bar;
            }
        }

        static { // this static block has complexity = 2
            qux = baz || quux;
        }
    }
}

选项

🌐 Options

此规则有一个数字或对象选项:

🌐 This rule has a number or object option:

  • "max"(默认:20)强制执行最大复杂度
  • "variant": "classic" | "modified"(默认值:"classic")要使用的圈复杂度变体

max

使用 max 属性自定义阈值。

🌐 Customize the threshold with the max property.

"complexity": ["error", { "max": 2 }]

已弃用: 对象属性 maximum 已弃用。请改用属性 max

或者使用简写语法:

🌐 Or use the shorthand syntax:

"complexity": ["error", 2]

variant

要使用的循环复杂度变体:

🌐 Cyclomatic complexity variant to use:

  • "classic"(default)- 经典 McCabe 循环复杂度
  • "modified" - 修改后的循环复杂度

修改后的圈复杂度 与经典圈复杂度相同,但每个 switch 语句只会将复杂度值增加 1,无论它包含多少个 case 语句。

🌐 Modified cyclomatic complexity is the same as the classic cyclomatic complexity, but each switch statement only increases the complexity value by 1, regardless of how many case statements it contains.

使用 { "max": 3, "variant": "modified" } 选项时,此规则的正确代码示例:

🌐 Examples of correct code for this rule with the { "max": 3, "variant": "modified" } option:

在线运行
/*eslint complexity: ["error", {"max": 3, "variant": "modified"}]*/

function a(x) {     // initial modified complexity is 1
    switch (x) {    // switch statement increases modified complexity by 1
        case 1:
            1;
            break;
        case 2:
            2;
            break;
        case 3:
            if (x === 'foo') {  // if block increases modified complexity by 1
                3;
            }
            break;
        default:
            4;
    }
}

上述函数的经典圈复杂度是 5,但修改后的圈复杂度只有 3

🌐 The classic cyclomatic complexity of the above function is 5, but the modified cyclomatic complexity is only 3.

何时不使用

🌐 When Not To Use It

如果你无法为你的代码确定适当的复杂性限制,那么最好禁用此规则。

🌐 If you can’t determine an appropriate complexity limit for your code, then it’s best to disable this rule.

版本

此规则是在 ESLint v0.0.9 中引入。

进阶读物

资源