编写优雅的 JavaScript 而不是 if-then 分支

Writing elegant JavaScript instead of if-then branches

如何使下面的代码更优雅和可读?

if (this.flag === 1) {
  this.value -= 0.1;
}
if (this.value <= 0) {
  this.flag = 0;
}

if (this.flag === 0) {
  this.value += 0.1;
}
if (this.value >= 1) {
  this.flag = 1;
}

编辑:假设,为了简单起见,我正在更改对象的不透明度,并且我希望它在某种循环中一遍又一遍地从 0 淡入淡出到 1。 .value是不透明度,.flag是告诉它什么时候切换方向。

根据你现在拥有的,我会这样做:

    if (this.flag === 1) {
      this.value -= 0.1;
    } else if (this.flag === 0) {
      this.value += 0.1;
    }

    if (this.value <= 0) {
      this.flag = 0;
    } else if (this.value >= 1) {
      this.flag = 1;
    }

但是flag可以是布尔值吗?如果是这样,您不需要进行数值检查。 this.value 也可以是 0-1 之间的任意值吗?在这种情况下未设置标志。如果可能的话,我会像这样重构代码,但这取决于您要实现的逻辑

    if (this.flag) {
      this.value -= 0.1;
    } else {
      this.value += 0.1;
    }
    if (this.value <= 0) {
      this.flag = 0;
    } else {
      this.flag = 1;
    }

可以使用如下shorthand符号简化一些if-else场景。

this.flag = this.value <= 0 ? 0 : 1;
this.value = this.value + (this.flag === 1 ? -0.1 : 0.1);

但是,您的脚本在其当前形式中使用独有的 if 条件,这些条件未涵盖 flagvalue 的所有可能值以及 else堵塞。根据您是否关心这一点,我上面的建议可能会破坏您的代码。


编辑 - 基于 OP 更新

flag 应该是布尔值 true/false.

this.flag = this.value > 0;
this.value += (this.flag ? -0.1 : 0.1);

编辑 2 - 基于评论

为什么要通过this.value的值来操作this.flag?该标志应通过其他方式控制,例如复选框或其他方式,因此您的不透明度更改脚本实际上应该是这样的:

this.value += (this.flag ? -0.1 : 0.1);

如果您想在不透明度达到 01 时自动切换标志,您可以这样做:

this.value += (this.flag ? -0.1 : 0.1);

if(this.value === 1 || this.value === 0) {
  this.flag = !this.flag;
}

请注意,这个答案已经超出了问题的范围,问题的范围是对条件有一个更优雅的方法。如果您需要进一步讨论,最好提出一个新的 SO 问题。

这会稍微改变结果,但我认为这是您真正想要的:

if (this.flag === 1) {
  this.value -= 0.1;
  if (this.value <= 0)
    this.flag = 0;
} else /* if (this.flag === 0) */ {
  this.value += 0.1;
  if (this.value >= 1)
    this.flag = 1;
}

虽然它可能仍然不够优雅,但它至少很容易理解,因为您的圈复杂度只有 4(而不是原始代码中的 16)。


要获得优雅的解决方案,您需要进行更多更改。您可以用变化量表示方向本身,而不是使用 "flag" 作为方向:

 this.value += this.dir;
 if (this.value >= 1)
     this.dir = -0.1;
 else if (this.value <= 0)
     this.dir = 0.1;

或者再一次,甚至

 this.value += this.dir;
 if (this.value <= 0 || this.value >= 1)
     this.dir *= -1;