特定の 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 で持ち上げる必要があります。一般を変換するには2つの解決策があります
<なんらかのステートメント(条件
?
then-expression:
else-expression ) >
if (
調子) {
<なんらかのステートメントthen-expression>
} else {
<何らかのステートメントの else-expression>
}
var helper;
if (
調子)
helper =
then式;
else
helper =
else式;
<ある声明
helper
>
どちらを選択するかは、いくつかのステートメントの複雑さに依存します (あなたのreturn
-statement の場合、私は #1 を選びます)。また、置換には独自の構文規則があるため、周囲のブロックを調整する必要さえあるかもしれません。これはすべて簡単な作業ではなく、変換する解析済みの AST が既にある場合にのみ自動化できます。
1 つのアイデアは、に変換x ? y : z
すること(x && y) || z
です。おそらく、三項演算子を見つけるためにかなり高度な解析を行う必要がありますが、少なくとも、必要な変更がはるかに少ないことを意味するステートメントではなく式として残すことができます。ただし、これら 2 つのことが完全に一致しない場合があることに注意してください (例:y
が 0 の場合)。そのため、このアプローチは注意して使用し、適用するコードをある程度制御できる場合にのみ使用してください。
の考え方(x && y) || z
は、x が true の場合は y に評価され、x が false の場合は z に評価されるというものです。これは、JavaScript がブール値以外の値のショートサーキットを処理する方法で、いくつかのエッジ ケースが原因で機能します。これは、標準のブール演算の一般化のようなものです。基本的に、JavaScript は、操作を実行するために検査する必要があった最後の値を返します。Soをtrue && (stuff)
返しますがstuff
、 をfalse && (stuff)
返しますfalse
。同様にをtrue || (stuff)
返しますがtrue
、 をfalse || (stuff)
返しますstuff
。
(x && y) || z
私たちが望むことを (ほとんど) 行うことを示すためにチェックする 2 つのケースがあります。
x は true であるため、 と(true && y) || z
評価されy || z
ます。y も真である場合、これは y に評価され、目的の動作が得られます。y が真でない場合、操作は失敗し、代わりに z が返されます!
x は falsey であるため、 は に(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"