关于javascript:if子句中的多个条件

Multiple conditions in an if clause

如果我有一份需要满足这些要求的国际单项体育联合会声明:

1
if(cave > 0 && training > 0 && mobility > 0 && sleep > 0)

有没有办法说所有的都大于零?只是为了更有效的干代码?

类似:

1
if(cave, training, mobility, sleep > 0)


使用math.min可以得到最小值,然后只需要对下限进行一次检查。

1
2
3
if(Math.min(cave, training, mobility, sleep) > 0) {
    //do something
}


可以将数组与.every一起使用。这不太干,但更详细:

1
2
3
4
5
6
var isGreaterThanZero = function(val) {
    return val > 0;
};
if([cave, training, mobility, sleep].every(isGreaterThanZero)) {
    // Do Something
}

我喜欢这样做的原因是,通过使用数组,很明显您在为每个变量重复逻辑。以一种明显的方式命名回调有助于未来的读者准确理解这种检查将实现什么。最后,这不仅为数字提供了范围,还为将来任何类型的检查提供了范围——任何复杂性都隐藏在if语句本身之外。


正如一些人所说,在if语句中使用多个简单条件没有任何错误,但是我会考虑将格式改为:

1
2
3
4
if ( cave > 0
   && training > 0
   && mobility > 0
   && sleep > 0 )

或者,我将从使用这些变量作为整数改为bool变量,即isCavehasTraining或类似变量,然后将适当的bool设置为更接近代码定义不同属性的位置(编辑:如果为false,可能会提前返回,以防止进一步的不必要的计算)。这将在下一个代码块中将if语句简化为后者,此外,它还显示了一个变量,如果条件变得稍微复杂,或者您希望简化if语句的读取:

1
2
3
4
5
6
7
8
var isCave =  cave > 0; # What does cave > 0 mean?
var hasTraining = training > 0;
var isMobile = mobility > 0;
var isNotSleeping = sleep > 0; # What does sleep > 0 indicate? Unclear

if (isCave && hasTraining && isMobile && isNotSleeping ) {
   // Do your thing
}

换句话说,if语句中的多个条件不是您最大的代码味道,我将把重点转移到为您的变量提供更好的名称,清楚地指示值的含义。这将提高对代码的阅读和理解,这比一些奇怪的语法更能避免多个if条件。


if语句中使用多个简单条件没有任何错误。但是,如果它不能放在一行中(大约80个字符),您就有一些解决方案。

最终,您不会检查四个变量是否大于零。您正在检查一组条件。这些条件(当前)由有符号整数表示的事实不仅不相关,而且是应该隐藏在函数中的实现细节。

  • 使用中间标志:

    10
  • 使用函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function can_do_this()
    {
        // split conditions into logical groups

        // checking location, because you need training if you're
        // in a cave
        if (cave <= 0 || training <= 0)
            return false;

        // checking status, because you have to be mobile and
        // sleepy
        if (mobility <= 0 || sleep <= 0)
            return false;

        return true;
    }

    if (can_do_this())
        // ...
  • 针对需要检查的个别条件使用函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function valid_location()
    {
        return (cave > 0 && training > 0);
    }

    function valid_status()
    {
        return (mobility > 0 && sleep > 0);
    }

    if (valid_location() && valid_status())
        // ...

  • 正如其他人所建议的,您可以使用。如果您不介意使用ES6或Polyfills:

    1
    2
    3
    4
    var hasAllStats = [cave, training, mobility, sleep]
      .every(function(stat) { return stat > 0; });

    if (hasAllStats) { }

    或者,您可以使用.some来获取反转(还需要es6或polyfill):

    1
    2
    3
    4
    var isMissingStats = [cave, training, mobility, sleep]
      .some(function(stat) { return stat <= 0; });

    if (!isMissingStats) { }

    如果不想使用ES6,可以使用Reduce:

    1
    2
    3
    4
    5
    6
    var hasAllStats = [cave, training, mobility, sleep]
      .reduce(function(hasAllStats, stat) {
        return hasAllStats && stat > 0;
      }, true);

    if (hasAllStats) { }


    听起来像是"验证器"函数的工作,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function areAllGreaterThanZero(){
        //TODO: check inputs
        var result = true;
        [].splice.apply(arguments).forEach(function(x){
            result = result && (x > 0);
        });
        return result;
    }

    if(areAllGreaterThanZero(cave, training, mobility, sleep)) {
        // ...
    }


    假设32位整数。

    1
    if ((cave | training | mobility | sleep) > 0)

    如果上述任何一个数字为负数,或的结果将为负数,并且不满足要求。

    编辑:任何一个参数为0时都不起作用。这是可行的,但它不会像其他方式那样高效、易读。

    1
    if (((cave | training | mobility | sleep) > 0) && (cave*training*mobility*sleep != 0))

    另一个更好的方法

    1
    if (!((cave | training | mobility | sleep) < 0))


    用木屑过滤:

    1
    2
    3
    4
    var data = [cave, training, mobility, sleep];
    var result = _.filter(data, function (datum) { return datum > 0; }).length === data.length;

    console.log(result);

    它迭代数组元素并返回由满足给定要求的元素组成的新数组,这些元素是> 0—如果结果数组的大小与给定的不同,则表示其中一个或多个元素不是> 0

    我专门写它是为了检查每个数组值(即使没有必要,因为第一个> 0可以给出相同的结果),而不是像您所说的那样,在第一个正数处停止检查所有数组值。

    PS您可以反转它来检查<= 0.length === 0是否安装得更快。


    为什么要寻找解决方案?

    Your question looks like best and simple answer, i recommend it. We have multiple solutions for this. Below one is that.

    .every()的jsbin

    通过使用每种功能来实现。

    1
    2
    3
    4
    5
    6
    7
    var flag = [cave, training, mobility, sleep].every(function(val) {
         return val > 0;
      });

    if(flag) {
      alert('All the elements are greater than Zero');
    }