3

特定的 JS 解析器(不在我的控制范围内)不理解嵌套的条件运算符语法,如下所示:

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

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

4

2 回答 2

5

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

我认为正则表达式不可能做到这一点——你需要用它们解析整个 JS 表达式语法。当然,您可以使用它们来查找三元运算符的外观,但需要手动替换它们。

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

<some statement ( condition ? then-expression : else-expression ) >

  1. if ( (健康)状况 ) {

    <一些语句然后表达式>

    } else {

    <some statement else-expression>

    }

  2. var helper;

    if ( (健康)状况 )

    helper = 然后表达式;

    else

    helper = 其他表达式;

    <一些声明 helper>

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

于 2013-02-04T17:10:04.727 回答
1

一种想法是转变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,而后者又计算为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"
于 2017-04-17T07:19:48.600 回答