【问题标题】:Replace conditional operator with if/else automatically?自动用 if/else 替换条件运算符?
【发布时间】:2013-01-19 08:22:30
【问题描述】:

一个特定的 JS 解析器(不在我的控制范围内)不理解这样的嵌套条件运算符语法:

return num === 1 ? condition ? condition : something : something;

因此,我想用 if/else 块替换文件中的所有条件运算符(简单和嵌套)。我该怎么做? (Textmate 或类似的正则表达式会很有帮助。)

【问题讨论】:

  • 它是有效的(试试1 ? 2 ? 3 : 4 : 5),但是子表达式中的returns 看起来很可疑(试试1 ? 2 ? 3 : return 4 : return 5)。
  • @chris 很公平,只是在试验它——我不确定。至于returns,我认为他基本上是指“收益”作为 exp 的值。尽管如此,将内部表达式括起来比完全更改为 if/else 更容易
  • @ChrisJester-Young,抱歉,子表达式中的返回值不应该存在。问题只是关于用 if/else 替换条件运算符表达式。代码是有效的JS。

标签: javascript regex replace conditional-operator


【解决方案1】:

我该怎么做? (Textmate 或类似的正则表达式会很有帮助。

我认为这对于正则表达式是不可能的——你需要用它们解析整个 JS 表达式语法。当然你可以使用它们来查找三元运算符的出现,但是替换它们需要手动完成。

这是因为条件运算符构成表达式,而 if/else 结构是语句。这意味着您将需要在 if-else 周围取消包含三元运算符的语句。改造一般有两种解决方案

(条件 ? then-expression : else-expression) >

  1. if ( 条件 ) {

    } else {

    }

  2. var helper;

    if ( 条件 )

    helper = 然后表达式;

    else

    helper = else-expression;

    helper>

选择哪一个取决于 some statement 的复杂性(对于您的return-statement,我会选择#1)。而且由于替换带来了自己的语法规则,您甚至可能需要调整周围的块。所有这一切都不是一件容易的事,而且只有当你已经有一个解析的 AST 来转换时,imho 才能自动化。

【讨论】:

    【解决方案2】:

    一个想法是将x ? y : z 转换为(x && y) || z。您可能仍然需要进行一些相当花哨的解析才能找到三元运算符,但至少您可以将它们保留为表达式而不是语句,这意味着所需的更改范围要小得多。但请注意,在某些情况下,这两个值可能不完全等效(例如,如果 y 为 0),因此请谨慎使用此方法,并且仅当您可以控制将应用于哪些代码时。

    (x && y) || z 的想法是,当 x 为真时,它的计算结果为 y,当 x 为假时,它的计算结果为 z。这是由于 JavaScript 处理非布尔值短路的方式中的一些边缘情况。这是标准布尔算术的一种概括。本质上,JavaScript 将返回它需要检查以执行操作的最后一个值。所以true && (stuff) 返回stuff,而false && (stuff) 返回false。同样true || (stuff) 返回true,而false || (stuff) 返回stuff

    有两种情况需要检查以表明(x && y) || z(大部分)做了我们想要的:

    案例 1:x 为真

    由于 x 为真,(true && y) || z 的计算结果为 y || z。如果 y 也是真实的,那么这将评估为 y 并且我们得到我们想要的行为。如果 y 不真实,则操作失败,我们得到 z!

    案例 2:x 是假的

    由于 x 为假,(false && y) || z 的计算结果为 false || z,而 false || z 的计算结果又为 z。在这里,我们很幸运,无论 y 是什么,我们总能得到想要的行为。

    示例

    以下是 chrome 控制台中所需行为的示例:

    > var x1 = "a" //truthy
    > var x2 = "" //falsey
    > var y = "y"
    > var z = "z"
    > (x1 && y) || z
    "y"
    > (x2 && y) || z
    "z"
    

    请注意y 不真实的情况!

    > var y2 = 0
    > (x1 && y2) || z
    "z"
    

    【讨论】:

    • 你的意思是if(x){ return y;} else { return z;}
    • @bowl0stu 我不确定你的意思。那将是一个陈述而不是一个表达,对吧?通过坚持使用短路布尔运算,您可以将其保留为表达式。
    • 我不明白(x && y) || z的目的。需要解释一下吗?
    • @bowl0stu 当然,我在答案中添加了解释,如果有什么不清楚的地方请告诉我
    • 谢谢老兄。以前从未听说过短路;有趣的概念
    猜你喜欢
    • 1970-01-01
    • 2013-01-19
    • 2019-10-20
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 2022-12-06
    相关资源
    最近更新 更多