JavaScriptは、「Don't break the web」ということを念頭に、仕様拡張なども構成されていっているのですが、時として妙なものも発生してしまいます。
falsyな値
JavaScriptにはfalsyな値が7つ(0
、-0
、NaN
、false
、null
、undefined
、''
)ある、ということは有名かと思います。…で、MDNを見てみると、8つ目の値が存在します。それが、document.all
です。
仕様としての挙動
通常のJavaScriptにfalsyとなるオブジェクトは存在しませんから、明らかに目立つ挙動なのですが、WHATWGの仕様を参照してみると、さらにすごい挙動をするとのことでした。
typeof document.all === 'undefined'
-
document.all == null
、document.all == undefined
(===
では等価になりません) -
document.all(引数)
のように呼び出すこともできる
「配列のようなオブジェクト」は数多くありますが、document.all
はさしずめ「undefined
のようなオブジェクト」、ということになってしまいます。
どうしてこうなった?
かつてはIE独自プロパティとして知られたdocument.all
ですが、使い方として(あまりよろしくない面もありますが)2通りのコードが存在していました。
-
if(document.all)
のように判定してIEの処理に分岐するもの - 存在チェックをせずに
document.all
を使うもの
後にIE以外のブラウザでも互換上document.all
が実装されることとなったのですが、if
チェックに対応するために、本来のJavaScriptの仕様にはない「falsyなオブジェクト」として実装された、とのことです。あまりに特殊なこともあって、ECMAScriptの仕様書にまで追加仕様が書かれています。
There are no other known examples of this type of object and implementations should not create any with the exception of
document.all
.
そりゃそうだ、こんなオブジェクトが他にあったら泣きたくもなるし。
結論
「Don't break the web」のためにはECMAScriptの仕様まで曲げてしまう、ときもある。