技術的な話をしましょう。ECMAScript Standard 262から引用してロジックを説明します。
式[] ? 1 : 2
は非常に単純です。
11.12 条件演算子 ( ? : )
- lref を LogicalOREExpression の評価結果とします。
- ToBoolean (GetValue(lref))が true の場合、
- 最初の AssignmentExpression を評価した結果を trueRef とします。
- GetValue(trueRef) を返します。
- そうしないと
- 2 番目の AssignmentExpression を評価した結果を falseRef とします。
- GetValue(falseRef) を返す
9.2 ToBoolean
- 未定義: false
- ヌル: false
- ブール値: 結果は入力引数と等しくなります (変換なし)。
- Number: 引数が +0、-0、または NaN の場合、結果は false です。それ以外の場合、結果は true です。
- 文字列: 引数が空の文字列 (長さがゼロ) の場合、結果は false です。それ以外の場合、結果は true です。
- オブジェクト: 真
それは本当です。
次に、二重等号演算子を使用したときに何が起こるかを見てみましょう。おそらくこれは、これを行うべきではない理由を説明するのに役立ちます。
== の動作は、セクション 11.9.3: 抽象等価比較アルゴリズムで説明されています。
x == y の場合、x = [] および y = false の場合、次のようになります。
11.9.3: 抽象等価比較アルゴリズム
Type(y) が Boolean の場合、比較の結果を返します x == ToNumber(y)
9.3 ToNumber
引数が
falseの場合、結果は+0です。
[] == 0
11.9.3: 抽象等価比較アルゴリズム
Type(x) が Object で Type(y) が String または Number の場合、比較ToPrimitive(x) == yの結果を返します。
9.1 プリミティブへ
オブジェクトのデフォルト値を返します。オブジェクトのデフォルト値は、オブジェクトの[[DefaultValue]] 内部メソッドを呼び出し、オプションのヒント PreferredType を渡すことによって取得されます。[[DefaultValue]] 内部メソッドの動作は、8.12.8 のすべてのネイティブ ECMAScript オブジェクトについて、この仕様によって定義されています。
8.12.8 デフォルト値:
O の [[DefaultValue]] 内部メソッドがヒントなしで呼び出されると、ヒントがNumberであるかのように動作します。
- valueOf をオブジェクト O の [[Get]] 内部メソッドを引数「valueOf」で呼び出した結果とする。
- IsCallable(valueOf) が true の場合、
- val を valueOf の [[Call]] 内部メソッドを呼び出した結果とし、O を this 値とし、引数リストを空にします。
- val がプリミティブ値の場合、val を返します
- オブジェクト O の [[Get]] 内部メソッドを引数 "toString" で呼び出した結果を toString とする。
- IsCallable(toString) が true の場合、
- str をtoStringの [[Call]] 内部メソッドを呼び出した結果とし、 O を this 値とし、引数リストを空にします。
- str がプリミティブ値の場合、str を返します。
結果は最初に使用したのと同じ配列であるため、これは最初に valueOf を試みてから拒否すると思います。次に、配列の toString を呼び出します。これは、その値のコンマ区切りリストとして普遍的に実装されているようです。このような空の配列の場合、空の文字列になります。
これで '' == 0 になりました
11.9.3: 抽象等価比較アルゴリズム
Type(x) が String で Type(y) が Number の場合、比較の結果を返すToNumber(x) == y
9.3.1 文字列型に適用される ToNumber
空であるか空白のみを含むStringNumericLiteral は+0に変換されます。
これで 0 == 0 になりました
11.9.3: 抽象等価比較アルゴリズム
x が y と同じ Number 値の場合、true を返します
素晴らしい。それは本当です。ただし、ここにたどり着くにはかなり複雑な方法です。