2008-05-27

いにしえの window.undefined ... jQuery の場合

JavaScriptにおける未定義値の判別方法
jQueryのundefined変数による判別は謎です。undefinedはECMA-262 3rdやJavaScript 1.3にGlobalオブジェクトの値プロパティとして定義されていました。もっとちゃんと調べないと。反省)。jQueryはこの判別方法を使っているので知らずに書き換えると予期しない動作をします…。
aquilegia さんの投稿の中で、jQuery の window.undefined の実装に対して疑問があった(過去形)ようなので、その経緯を調べてみました。

その経緯は jQuery General Discussion の中にそれらしき議論がありました。どうやら、window.undefined というグローバルオブジェクトは、jQuery 1.0 の開発中に導入したものらしいです。

もともとは、undefined と判定すべき箇所が、null 判定していたことに起因するようです。
foo === null は foo === undefined の誤りでは?
ですが、undefined は IE5.0 とそれ以前では使えない ので、次のように表現し直そうとしたみたいです。
typeof foo === 'undefined' 
ですが、この表現を好まないとして、次のように window.undefined を用意したようです。
window.undefined = window.undefined;
これにより、IE 5.0 とそれ以前を含む古いブラウザでも undefined が使えるようになって、かつ ECMA-262 3rd の undefined グローバルオブジェクトの要件も満たすということです。

次のようにしても、同じ効果があるとの説明もありました。スコープの影響を受けるので、汎用ライブラリには向かないかもしれませんね。
var undefined;
で、aquilegia さんが提案するとおり、undefined の判定は void 演算子を使うのが確実そうなんですが、IE 3 まで遡ると void 演算子がない ようですね。

だとすると、jQuery の window.undefined という実装は、undefined の書き換えの不都合は抱えますが、かなり広範囲でブラウザの互換性を実現する手段となっているということになりますね。

ちょっと専門外の話題に言及したので、知識が曖昧な部分があったかもしれません。誤りがあれば aquilegia さんが訂正してくれるだろうと期待してます。

1 件のコメント:

aquilegia さんのコメント...

そういうことでしたか、ありがとうございます。NN4は問題ないですが、確かにIE5以前は未定義の変数を参照するとエラーになるので、それを考慮してというのが大きな要因となっていそうです。
それと1.1.3.1→1.1.4の間のr2818で「window.undefined = window.undefined」が削除されているのですが、コミットログに理由が書かれておらずはっきりとしたことはわかりませんでした。IE5以前をサポートしないからなのだと推測しています。