a = [] ? 1 : 2
ここで a が1 に等しくなり、ここでb = [] == true ? 1 : 2
b が 2 に等しくなる理由を誰か説明できますか?
6 に答える
非常によく似たケースは、なぜ( '0'?'a':'b')が( '0' == true?'a':'b')とは異なる動作をするのかで処理されます。
要するに:
ブールコンテキストで評価される単一の値がある場合、ブール値に変換される
ToBoolean
ために渡されます。ただし、値をと比較すると、ECMAScript仕様のセクション11.9.3の
==
アルゴリズムが実行されます。このアルゴリズムでは、両方のオペランドが文字列または数値に変換され、これらの値が比較されます。
より詳細な説明
a = [] ? 1 : 2
を呼び出すことにより、条件がブール値に変換さToBoolean(GetValue(lref))
れます。ここで、オブジェクトGetValue
の場合、オブジェクト自体を返すだけで、すべてのオブジェクトがに評価されるtrue
と仮定します。
配列は単なるオブジェクトであるため、この式の結果はです1
。
b = [] == true ? 1 : 2
すでに述べたように、ここではかなりの型変換が行われています。
まず、true
数値に変換されます。
7. Type(y)がブール値の場合、比較の結果x == ToNumber(y)を返します。
だから私たちは
[] == 1
次に、ステップ9が適用されます。
9. Type(x)がObjectで、Type(y)がStringまたはNumber
の場合、比較ToPrimitive(x)==yの結果を返します。
つまり[]
、プリミティブ値(文字列または数値)に変換されます。ToPrimitive
関数(およびセクション8.12.8 )に従うと、要素を。で連結することにより、配列が文字列に変換されることがわかります,
。要素がない空の配列なので、結果は空の文字列になります。
だから私たちは
"" == 1
次に、ステップ5が適用されます。
5. Type(x)がStringで、Type(y)がNumberの場合、比較の結果ToNumber(x)==yを返します。
空の文字列はに変換されるため0
、0 == 1
でfalse
あり、条件演算子はを返します2
。
最初の例では、配列はブール値に変換されており、null、undefined、 ""、0、またはfalseではないためtrueになります。
2番目の例では、equals演算子が原因で型変換が行われています。mdnから:
2つのオペランドが同じタイプでない場合、JavaScriptはオペランドを変換してから、厳密な比較を適用します。いずれかのオペランドが数値またはブール値の場合、可能であれば、オペランドは数値に変換されます。
コンソールで次のことを試しました。
Number(true) //gives 1
Number([]) //gives 0
したがって、数値に変換すると、これらは等しくなりません。
配列はオブジェクトであるため、オブジェクトがブール比較のコンテキストで評価される場合、それは「真実」ですが、正確には真実ではありません。
では、またはでない場合a = [] ? 1 : 2
に戻ります。1
[]
null
undefined
ではb = [] == true ? 1 : 2
、がの1
場合に返されますが、そうではないため、 が返されます。[]
true
2
で配列を初期化すると[]
trueが返され、そうで[] == true
はないため:-)
1 つ目は代入であるため、true にフォールスルーする必要があります (ただし、何も等価ではありません)。空を真とみなすと偽になります。