JavaScript
dom
ECMAScript
InternetExplorer

document.allという名の亡霊

JavaScriptは、「Don't break the web」ということを念頭に、仕様拡張なども構成されていっているのですが、時として妙なものも発生してしまいます。

falsyな値

JavaScriptにはfalsyな値が7つ(0-0NaNfalsenullundefined'')ある、ということは有名かと思います。…で、MDNを見てみると、8つ目の値が存在します。それが、document.allです。

仕様としての挙動

通常のJavaScriptにfalsyとなるオブジェクトは存在しませんから、明らかに目立つ挙動なのですが、WHATWGの仕様を参照してみると、さらにすごい挙動をするとのことでした。

  • typeof document.all === 'undefined'
  • document.all == nulldocument.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の仕様まで曲げてしまう、ときもある。