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)强制最大复杂度

    ¥"max" (default: 20) enforces a maximum complexity

  • "variant": "classic" | "modified"(默认值:"classic")要使用的循环复杂度变体

    ¥"variant": "classic" | "modified" (default: "classic") cyclomatic complexity variant to use

max

使用 max 属性自定义阈值。

¥Customize the threshold with the max property.

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

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

¥Deprecated: the object property maximum is deprecated. Please use the property max instead.

或者使用简写语法:

¥Or use the shorthand syntax:

"complexity": ["error", 2]

variant

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

¥Cyclomatic complexity variant to use:

  • "classic"(默认) - 经典 McCabe 循环复杂度

    ¥"classic" (default) - Classic McCabe cyclomatic complexity

  • "modified" - 修改后的循环复杂度

    ¥"modified" - Modified cyclomatic complexity

修改后的循环复杂度与经典循环复杂度相同,但每个 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 中引入。

进阶读物

资源

ESLint 中文网
粤ICP备13048890号