理解嵌套三元运算符的简便方法?

时间:2014-04-10 19:25:51

标签: javascript ternary-operator ternary-tree

是否有一个简单的启发式方法来理解如何读取嵌套的三元运算符? 我在某人的源代码中遇到过这个问题并且无法理解它。一个简单的三元组很简单:

isRed = color == 'red' ? true : false

但您如何阅读以下内容?我可以将第一个与最后一个对齐,第二个与第二个对齐,或者我必须将其解析为我脑中的if / else树吗?

var offset =
  ( hasFrozenRows )
    ? ( options.frozenBottom )
    ? ( row >= actualFrozenRow )
    ? ( h < viewportTopH )
    ? ( actualFrozenRow * options.rowHeight )
    : h
    : 0
    : ( row >= actualFrozenRow )
    ? frozenRowsHeight
    : 0
    : 0;

翻新,它看起来像这样,几乎可以理解(?)

      var offset =
        ( hasFrozenRows ) ?
          ( options frozenBottom ) ?
            ( row >= actualFrozenRow ) ?
              ( h < viewportTopH ) ?
                ( actualFrozenRow * options.rowHeight )
                :
                h
              :
              0
            :
            ( row >= actualFrozenRow ) ?
              frozenRowsHeight
              :
              0
            :
            0;

3 个答案:

答案 0 :(得分:2)

对于像这样凌乱的东西,你必须从外面工作。基本上,这映射到的是:

if ( hasFrozenRows ) {
  if ( options.frozenBottom ) {
    if ( row >= actualFrozenRow ) {
      if ( h < viewportTopH ) {
        return ( actualFrozenRow * options.rowHeight )
      } else {
        return h;
      }
    } else {
      return 0;
    }
  } else {
    if ( row >= actualFrozenRow ) {
      return frozenRowsHeight
    } else {
      return 0
    }
  }
} else {
  return 0;
}

我认为我使用的遗留代码是一场噩梦......

我建议通过像Jasmine这样的单元测试器运行它,并将输出与原始代码进行比较,以确认它是相同的。

答案 1 :(得分:2)

如果您尝试将其视为一系列check thisif true then thiselse that,我认为您可以获得更多运气。

为此,将?:运算符放在行的开头可能会更容易,并将它们读作流程图上的箭头,标记为&#34;是&# 34;和&#34;不&#34;。 e.g:

cond1 
  ? cond2 
    ? cond3 
      ? res1 
      : res2
    : res3
  : res4

可以理解为:

cond1?
  yes -> is cond2 
    yes -> is cond3?
      yes -> res1 
      no -> res2
    no -> res3
  no -> res4

这仍然没有使这个可读,我同意所有的评论说这种代码应该真的被重写为可读。

答案 2 :(得分:2)

  

我必须将它解析成我头脑中的if / else树吗?

是的,因为在这种情况下,树而不是简单的链接运算符。这些很容易理解:-)如果没有缩进,这肯定需要重构。

在这种特殊情况下,否定条件也会有所帮助,因为它将条件和效果直接放在一起,使阅读变得更容易:

var offset = (!hasFrozenRows)
               ? 0
               : (!options.frozenBottom)
                 ? (row < actualFrozenRow)
                   ? 0
                   : (h < viewportTopH)
                     ? actualFrozenRow * options.rowHeight
                     : h
                 : (row >= actualFrozenRow)
                   ? frozenRowsHeight
                   : 0;

我们还可以将重复的row >= actualFrozenRow比较提升一级:

var offset = (!hasFrozenRows)
             ? 0
             : (row < actualFrozenRow)
               ? 0
               : (!options.frozenBottom)
                 ? frozenRowsHeight
                 : (h < viewportTopH)
                   ? actualFrozenRow * options.rowHeight
                   : h;

......这实际上使它完全可以理解,即使没有否定:

var offset = ( hasFrozenRows )
             ? ( row >= actualFrozenRow )
               ? ( options.frozenBottom )
                 ? ( h < viewportTopH )
                   ? actualFrozenRow * options.rowHeight
                   : h
                 : frozenRowsHeight
               : 0
             : 0;

您现在还可以看到您可以将前两个条件合并到hasFrozenRows && row >= actualFrozenRow