gpt4 book ai didi

javascript - 如何重构此函数以将其认知复杂度从 17 降低到允许的 15

转载 作者:行者123 更新时间:2023-12-04 04:02:27 26 4
gpt4 key购买 nike

  • 如何重构此函数以降低复杂性
  • 当我当时使用开关盒时,代码复杂性更多,如何减少它

    How to achive this




  • var has = Object.prototype.hasOwnProperty



    var toString = Object.prototype.toString


    function isEmpty(val) {

    if (val == null) return true
    if ('boolean' == typeof val) return false
    if ('number' == typeof val) return val === 0
    if ('string' == typeof val) return val.length === 0
    if ('function' == typeof val) return val.length === 0
    if (Array.isArray(val)) return val.length === 0
    if (val instanceof Error) return val.message === ''
    if (val.toString == toString) {
    switch (val.toString()) {
    case '[object File]':
    case '[object Map]':
    case '[object Set]': {
    return val.size === 0
    }
    case '[object Object]': {
    for (var key in val) {
    if (has.call(val, key)) return false
    }

    return true
    }
    }
    }
    return false
    }
    module.exports = isEmpty

    最佳答案

    我最近回答了一个非常相似的问题,更详细地介绍了认知复杂性的工作原理(参见 https://stackoverflow.com/a/62867219/7730554)。
    但总的来说,我认为了解 很重要。如果存在嵌套条件,认知复杂性会增加更多 .这种计算是这样完成的,因为人脑可以更好地处理按顺序编写的语句而不是嵌套条件。因此,对于每个条件语句(if、switch、for 循环等),复杂度值都会增加 +1。但是对于每个嵌套条件,在最后一级的顶部添加另一个 +1。这意味着,if 中的 if 不仅会添加 +1,还会添加 +2。如果,在 if 中,在 if 中,将导致第一个 if 条件 +1,第二个 if 条件 +2 和第三个 if 条件 +3。如果您想更深入地了解这一点,我建议您查看:https://www.sonarsource.com/docs/CognitiveComplexity.pdf
    因此,让我们首先分析您的方法中高复杂度值的来源:

    function isEmpty(val) {
    if (val == null) return true // +1
    if ('boolean' == typeof val) return false // +1
    if ('number' == typeof val) return val === 0 // +1
    if ('string' == typeof val) return val.length === 0 // +1
    if ('function' == typeof val) return val.length === 0 // +1
    if (Array.isArray(val)) return val.length === 0 // +1
    if (val instanceof Error) return val.message === '' // +1
    if (val.toString == toString) { // +1
    switch (val.toString()) { // +2
    case '[object File]':
    case '[object Map]':
    case '[object Set]': {
    return val.size === 0
    }
    case '[object Object]': {
    for (var key in val) { // +3
    if (has.call(val, key)) return false // +4
    }

    return true
    }
    }
    }
    return false
    }
    如果您查看我添加的注释,您可以很容易地看到与圈复杂度相关的最有问题的代码位于何处。这也与代码的人类可读性有关。
    因此,只需一步即可到达 增加可读性同时 降低认知复杂性 是寻找“ 早期返回 ”的选项。
    为了说明这一点,我简单地反转语句 *if (val.toString == toString)"以立即返回 false if *val.toString != toString":
    function isEmpty(val) {
    if (val == null) return true // +1
    if ('boolean' == typeof val) return false // +1
    if ('number' == typeof val) return val === 0 // +1
    if ('string' == typeof val) return val.length === 0 // +1
    if ('function' == typeof val) return val.length === 0 // +1
    if (Array.isArray(val)) return val.length === 0 // +1
    if (val instanceof Error) return val.message === '' // +1
    if (val.toString != toString) { // +1
    return false;
    }

    switch (val.toString()) { // +1
    case '[object File]':
    case '[object Map]':
    case '[object Set]': {
    return val.size === 0
    }
    case '[object Object]': {
    for (var key in val) { // +2
    if (has.call(val, key)) return false // +3
    }
    return true
    }
    }
    }
    现在最后一个 switch 语句可以在 if 语句之外执行,我们将嵌套级别减少了一层。通过这个简单的改变认知 复杂性 现在有 降至 14 而不是 17。
    然后,您甚至可以更进一步,通过将返回值提取到变量中来更改最后一个 case 语句,或者从代码块中提取一个单独的方法。这将进一步降低 isEmpty() 方法的复杂性。
    除了提取方法之外,您还可以使用声明性方法并使用,例如 Array 方法 find() ,这将进一步降低认知复杂性。
    为了说明这个想法,我做了两个:
    function isEmpty(val) {
    if (val == null) return true // +1
    if ('boolean' == typeof val) return false // +1
    if ('number' == typeof val) return val === 0 // +1
    if ('string' == typeof val) return val.length === 0 // +1
    if ('function' == typeof val) return val.length === 0 // +1
    if (Array.isArray(val)) return val.length === 0 // +1
    if (val instanceof Error) return val.message === '' // +1
    if (val.toString != toString) { // +1
    return false;
    }

    return checkForComplexTypes(val)
    }

    function checkForComplexTypes(val) {
    var result = null
    switch (val.toString()) { // +1
    case '[object File]':
    case '[object Map]':
    case '[object Set]': {
    result = val.size === 0
    }
    case '[object Object]': {
    result = Object.keys(val).find(key => has.call(val, key))
    }
    return result
    }
    }
    这应该 降低认知复杂性 isEmpty() 方法的 至 8 完整代码 包括提取的 checkForComplexTypes() 函数 复杂度得分为 9 .
    注意:JavaScript 目前不是我的主要语言,所以我不能完全保证最后一个重构步骤的正确性。

    关于javascript - 如何重构此函数以将其认知复杂度从 17 降低到允许的 15,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62872718/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com