javascript - 如何重构javascript中的条件逻辑?

标签 javascript refactoring conditional-statements

我继承了一个用于浏览和配置产品的大型 JavaScript (MooTools) 应用程序。

其中有一个跟踪产品配置状态的函数。根据产品所处的状态调用其他函数。

我扩展它以添加一些新功能,但最终在一个大 switch 语句中出现了一堆嵌套条件。

我的问题是,您如何重构条件逻辑?是否有用于跟踪状态的通用(或 JS 特定)模式/技术?

更新:这里有一个伪版本的函数来说明问题:

switchToVariation: function(link) {

  // set the variables      
  // before switch, set state    

  switch ( nextType ) {   
    case 'type1':
      if ( prevType == 'type1' ) {        
        if ( nextIsSameVariation ) {            
          // do stuff                                           
        } else {                                                                              
          if ( nextIsSomethingElse ) {              
            // do stuff
          }          
          // more stuff                      
        }
      } else {        
        // different stuff        
      }
      break;

    case 'type2':        
      if ( prevWasType1 ) {
        // stuff
      } else {
        if (nextIsSameStyle) {
          // stuff
        }
        // more stuff
      }    
      break;    

    default:                       
      // default stuff        
  }          

  // after switch, set state

}

最佳答案

当然,主要的答案是:将其分解成更小的部分,每个部分都做好一件事。

如果没有看到示例很难说得更具体,但是您说过“...在一个大的 switch 语句中有一堆条件...”这无疑提供了改进的机会:您可以移动每个案例都有自己的功能。

如果这样做,您有两个选择:要么使函数仅使用您传递给它们的参数工作,这往往会使事情更加模块化,要么使在外部函数中操作数据的函数闭包。我想说后者不太理想——对于这些目的——但这样做可能更快,因此是一个“速赢”。

假设我们最初有:

function myBigFunction() {
    var v1, v2, v3;

    /* ...set v1, v2, and v3 to various things...*/

    switch (condition) {
        case foo:
            /* ...do lots of stuff involving v1 and v2...*/
            break;

        case bar:
            /* ...do lots of stuff involving v1 only...*/
            break;

        case charlie:
            /* ...do lots of stuff involving v2 and v3...*/
            break;
    }
}

然后:

第一种选择:完全独立的功能:

function myBigFunction() {
    var v1, v2, v3;

    /* ...set v1, v2, and v3 to various things...*/

    switch (condition) {
        case foo:
            doFooStuff(v1, v2);
            break;

        case bar:
            doBarStuff(v1);
            break;

        case charlie:
            doCharlieStuff(v2, v3);
            break;
    }
}

function doFooStuff(v1, v2) {
}

function doBarStuff(v1) {
}

function doCharlieStuff(v2, v3) {
}

...当然,您可能需要让这些函数返回一些内容然后进行处理,例如:

    case foo:
        v1 = doFooStuff(v1, v2);
        break;

...如果 doFooStuff 需要更新 v1。如果它需要更新 v1v2,你可以返回一个数组,或者创建 v1v2 属性您传递给 doFooStuff 等的对象。这是使用属性的示例:将 v1v2 属性替换为对象 ( vdata) 上有 v1v2 properties:

var vdata = {
    v1: "someInitialValue",
    v2: "someInitialValue"
};

...然后调用 doFooStuff:

    case foo:
        doFooStuff(vdata);
        break;

...这允许 doFooStuff 更新 v1v2。但要小心,您不想创建一个包含所有 myBigFunction 变量的厨房水槽,那样会牺牲模块化。

第二种选择:使用闭包并直接使用父函数的数据:

function myBigFunction() {
    var v1, v2, v3;

    /* ...set v1, v2, and v3 to various things...*/

    switch (condition) {
        case foo:
            doFooStuff();
            break;

        case bar:
            doBarStuff();
            break;

        case charlie:
            doCharlieStuff();
            break;
    }

    function doFooStuff() {
        // work with v1 and v2 directly
    }

    function doBarStuff() {
        // work with v1 directly
    }

    function doCharlieStuff() {
        // work with v2 and v3 directly
    }
}

请注意,这里的各种子例程都是 myBigFunction 中的闭包,因此它们可以直接访问所有 myBigFunction 的局部变量。这是更加模块化的,但不完全是第一个选项的完整模块化方法。这也像是局部版本的函数处理全局变量的问题:副作用很容易引入并且会引起麻烦。

首选第一个选项,但如果不切实际,第二个选项至少可以帮助您使主线逻辑更清晰。当然,两者结合也可能有效。

关于javascript - 如何重构javascript中的条件逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3767659/

相关文章:

javascript - 当执行打开时

Python numpy where 函数行为

javascript - 为什么空 JavaScript 数组在条件结构中的计算结果为真?

javascript - Google reCAPTCHA float 通知未完全显示

javascript - 如何将两个按钮放在同一水平线上?

java - 正确高效的编程风格

javascript - 如何重构这个多重嵌套的 if else block

javascript - 使用单选按钮和复选框的 Acrobat JavaScript 计算

javascript - OnClick Javascript 似乎无法正常工作

java - 重构 Java Servlets - 寻找一个好的命名方案