特定的 JS 解析器(不在我的控制范围内)不理解嵌套的条件运算符语法,如下所示:
return num === 1 ? condition ? condition : something : something;
因此,我想用 if/else blocks 替换文件中的所有条件运算符(简单和嵌套)。我该怎么做?(Textmate 或类似的正则表达式会很有帮助。)
特定的 JS 解析器(不在我的控制范围内)不理解嵌套的条件运算符语法,如下所示:
return num === 1 ? condition ? condition : something : something;
因此,我想用 if/else blocks 替换文件中的所有条件运算符(简单和嵌套)。我该怎么做?(Textmate 或类似的正则表达式会很有帮助。)
我该怎么做?(Textmate 或类似的正则表达式会很有帮助。
我认为正则表达式不可能做到这一点——你需要用它们解析整个 JS 表达式语法。当然,您可以使用它们来查找三元运算符的外观,但需要手动替换它们。
这是因为条件运算符构成表达式,而 if/else 结构是语句。这意味着您需要在 if-else 周围取消包含三元运算符的语句。改造一般有两种解决方案
<some statement ( condition
?
then-expression:
else-expression ) >
if (
(健康)状况) {
<一些语句然后表达式>
} else {
<some statement else-expression>
}
var helper;
if (
(健康)状况)
helper =
然后表达式;
else
helper =
其他表达式;
<一些声明
helper
>
选择哪一个取决于some 语句的复杂性(对于您的return
-statement,我会选择 #1)。而且由于替换带来了自己的语法规则,您甚至可能需要调整周围的块。所有这一切都不是一件容易的事,而且只有当你已经有一个解析的 AST 来转换时,imho 才能自动化。
一种想法是转变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
(大部分)做了我们想要的:
由于 x 为真,(true && y) || z
计算结果为y || z
。如果 y 也是真实的,那么这将评估为 y 并且我们得到我们想要的行为。如果 y 不真实,则操作失败,我们得到 z!
由于 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"