[ ] == false //=> true ![ ] //=> false [ ] == ![ ] //=> true if([ ]) alert('True') //=> alert('True')
falseと==で比較して真になるという仕様の意味がわからない。
2010-02-23追記:
「Under Translation of ECMA-262 3rd Edition」という日本語文書があったので見てみた。 http://www2u.biglobe.ne.jp/~oz-07ams/2002/ecma262r3/index.html
11.9.3 抽象的等価比較アルゴリズム (The Abstract Equality Comparison Algorithm)
x と y を値とする比較 x==y は、 true または false を生成する。次のように比較は実行される:
1. Type(x) と Type(y) が異なる場合は、ステップ 14 へ。
2. Type(x) が Undefined ならば、 true を返す。
3. Type(x) が Null ならば、 true を返す。
4. Type(x) が Number でなければ、ステップ 11 へ。
5. x が NaN ならば、 false を返す。
6. y が NaN ならば、 false を返す。
7. x が y と同じ数ならば、 true を返す。
8. x が +0 で y が -0 ならば、 true を返す。
9. x が -0 で y が +0 ならば、 true を返す。
10. false を返す。
11. Type(x) が String ならば、x と y の文字シーケンスが完全に同じ(同じ長さで対応する位置に同じ文字がある)なら true を返し、そうでなければ false を返す。
12. Type(x) が Boolean ならば、 x と y がともに true かともに false なら true を返し、そうでなければ false を返す。
13. x と y が同じオブジェクトを参照しているか、または互いに結合しているオブジェクト(セクション13.1.2) を参照していれば true を返し、そうでなければ false を返す。
14. x が null で y が undefined ならば、 true を返す。
15. x が undefined で y が null ならば、 true を返す。
16. Type(x) が Number で Type(y) が String ならば、比較 x == ToNumber(y) の結果を返す。
17. Type(x) が String で Type(y) が Number ならば、比較 ToNumber(x) == y の結果を返す。
18. Type(x) が Boolean ならば、比較 ToNumber(x) == y の結果を返す。
19. Type(y) が Boolean ならば、比較 x == ToNumber(y) の結果を返す。
20. Type(x) が String か Number で Type(y) が Object ならば、比較 x == ToPrimitive(y) の結果を返す。
21. Type(x) が Object で Type(y) が String か Number ならば、比較 ToPrimitive(x) == y の結果を返す。
22. false を返す。
これを元に、
[ ] == false
の比較を追って解析していく。
1 → 19 で、
[ ] == ToNumber(false) [ ] == +0 // ToNumber(false) については、9.3 ToNumber に記述有り
さらに21で、
ToPrimitive([ ]) == +0 [ ]のDefaultValue(hint) == +0 // ToPrimitive([ ]) については、9.1 ToPrimitive に記述有り [ ]のGet(toString) == +0 // DefaultValueについては 8.6.2.6 [[DefaultValue]] (hint) に記述有り [ ].toString() == +0 // Get(toString)については 8.6.2.1 [[Get]] (P) に記述有り "" == +0 // [ ].toString は空文字列
こんどは17で、
toNumber("") == +0
toNumber("") については、「9.3.1 String 型に適用される ToNumber (ToNumber Applied to the String Type) 」に以下の記述がある。
文字列に適用される ToNumber は、入力文字列に 次の文法を適用する。文法が文字列を StringNumericLiteral として解釈不能ならば、 ToNumber の結果は NaN である。
StringNumericLiteral :::
StrWhiteSpace(opt)
StrWhiteSpace(opt) StrNumericLiteral StrWhiteSpace(opt)
(中略)
# StringNumericLiteral ::: [empty] の数学値は、 0 である。
(中略)
一旦数値文字列リテラルの厳密な数学値が決定されたら、 Number 型の値に丸められる。数学値が 0 ならば、丸められる値は、数値文字列リテラル内の最初の非空白文字が '-' でなければ +0 であり、 '-' ならば -0 である。
ここから、空文字列の場合も StringNumericLiteral と見なされ、その数学値は 0 であり、最終的な値は +0 となる。
従って、
+0 == +0
となり、上記アルゴリズム7で true となる。
長い。。。。。数学の証明問題みたい。MozillaサイトのJavaScriptリファレンスもざっと見たが、同じような事が別の書き方で書いてある。
つまり、空リストは、
・論理値と評価される文脈では、true となる*1
・数値や論理値と等値比較される文脈では 0 となる
という分かりにくい仕様だ。
*1:「9.2 ToBoolean」に記述がある