如何阅读这个复杂的Javascript快捷方式操作符?

时间:2013-05-07 21:49:12

标签: javascript

我潜入了另一个开发人员的代码并遇到了这条疯狂的线条。看起来有很多比较正在进行,但无法绕过它。

num > -1 ? "down" === position && value >= this._offset ? this.hideFunc() : "up" === position && value >= this._offset && this.showFunc() : this.showFunc()

我怎么能解读这个?

4 个答案:

答案 0 :(得分:7)

if (num > -1) {
    if ( "down" === position && value >= this._offset ) {
       return this.hideFunc();
    } else if ("up" === position && value >= this._offset) {
       return this.showFunc();
    } else {
       return; //Doesn't exist in the one liner but the function must return something..
    }
} else {
    return this.showFunc();
}

答案 1 :(得分:1)

Operator Precedence告诉我们ternary operators是最外面的,然后是AND和比较。写一个更好(更清晰)的方法是

(num > -1)
  ? ( (("down" === position) && (value >= this._offset))
      ? this.hideFunc()
      : (("up" === position) && (value >= this._offset)) && this.showFunc() )
  : this.showFunc()

(仅为了明确性添加了括号,您可以省略它们 - 在缩进中有足够的信息)

现在你只有"需要了解AND运算符的short-circuit evaluation才能看出它是一种复杂的写作方式

if (num > -1)
    if (value >= this._offset) {
        if ("down" === position)
            this.hideFunc();
        else if ("up" === position)
            this.showFunc();
    }
else
    this.showFunc();

(并从函数调用或false获取返回值)

答案 2 :(得分:1)

有趣的是,似乎这里的所有其他答案都错过了解构三元运算符的一个潜在分支。

if (num > -1) {
    if ( "down" === position && value >= this._offset ) {
       return this.hideFunc();
    } else if ("up" === position && value >= this._offset) {
       return this.showFunc();

    /*** HERE'S THE BRANCH OTHER ANSWERS MISS ***/
    } else {
       return false;
    }

} else {
    return this.showFunc();
}

这来自你问题中可怕的三元表达的特定部分:

"up" === position && value >= this._offset && this.showFunc()

我们可以将其分解为两个分支:

"up" === position && value >= this._offset

显然,表达式实际上也是两个分支;但我们可以肯定,在任何一种情况下,结果都可以是truefalse如果结果是true那么我们将会看到

this.showFunc()

否则,短路逻辑已经导致false的结果。因此缺少分支。

具体:如果出现这种情况:

  • num大于-1,AND:
  • position既不是"down"也不是"up",也不是
  • position"up“但value小于this._offset

三元表达涵盖了这种情况,这个答案也是如此。其他答案没有(代码将一直通过并导致undefined)。

公平地说:结果是没有被使用(如果原始代码确实是你所包含的单行代码),在这种情况下没有功能差异。但是,我觉得有必要写这个答案主要是为了强调测试现有功能的任何重构的重要性,即使先前的代码很可怕,甚至在分析时也要小心。

答案 3 :(得分:0)

@MajidL向您展示了它是什么,但不是如何破译它。

这就是所谓的ternary operator,它们很难理解。

所以为了制止它,你有第一个声明:

num > -1 

在其他任何事情之前进行评估,如果它是真的,它会落入第二个三元运算符, &&运算符结合:

"down" === position && value >= this._offset

由于这也是一个三元运算符,它也有一个else但也恰好是if支票:

"up" === position && value >= this._offset

所以你最终得到了这个结构:

if(num > -1){
    if("down" === position && value >= this._offset){

    }else if("up" === position && value >= this._offset){

    }  
}else{

}

这使您无法确定返回值与检查的对应关系。这实际上是IMO的棘手部分。

最后一个返回值实际上是最简单的,它将始终属于第一个三元运算符的else,因为外部运算符被认为是第一个。所以这个:

this.showFunc();

像这样进入我们的结构:

if(num > -1){
    if("down" === position && value >= this._offset){

    }else if("up" === position && value >= this._offset){

    }  
}else{
    return this.showFunc();
}

留下中间检查。这是你的其他开发人员偷偷摸摸而且不易维护的地方,他使用外部值作为两个三元操作的返回值。我不建议这样做。

这也意味着内部值this.hideFunc()只能属于内部三元运算符,我们最终会得到完整的语句。

if(num > -1){
    if("down" === position && value >= this._offset){
        return this.hideFunc();
    }else if("up" === position && value >= this._offset){
        return this.showFunc();
    }  
}else{
    return this.showFunc();
}