関数の型を判断する場合、通常は typeof メソッドを使用します。通常は、期待どおりの効果が得られます。ただし、詳細についてはあまり知られていない部分もあります。これらの詳細を分析した後、John Resig は完璧なソリューションを提供してくれました。これについては、この記事で詳しく紹介します。
1. 知られざる伝統工法の詳細
関数の型を決定するときは、次のような typeof メソッドを使用することに疑いの余地はありません。
関数 fn(){
//コンテンツ
}
alert(typeof fn)//結果は「関数」です。
ただし、この方法は一部のブラウザでは期待どおりに機能しません。
1. Firefox2 および Firefox3
これら 2 つのブラウザでは、typeof を使用して HTML オブジェクト要素の型を検出すると、HTMLDocument などの「オブジェクト」ではなく不正確な「関数」の結果が返されます。のように:
アラート(HTMLドキュメントの種類);
//Firefox2 では、結果は「関数」になります。
//Firefox3 では、結果は「オブジェクト」になります。
2.Firefox2
正規表現の場合、このブラウザで返される結果は次のような「関数」です (Firefox3 では結果は「オブジェクト」です)。
var reg = /test/;
アラート(登録の種類);
//Firefox2 では、結果は「関数」になります。
//Firefox3 では、結果は「オブジェクト」になります。
注: Safari でテストしましたが、結果も「機能」でした。
3.IE6とIE7
IE で DOM 要素に対して typeof メソッドを使用すると、結果は「object」になります。のように:
alert(ドキュメントの種類.getElementsByTagName("body")[0].getAttribute);
// 結果は「オブジェクト」
4.サファリ3
Safari は、DOM 要素の NodeList が次のような関数であると考えます。
アラート(document.body.childNodes のタイプ);
//結果は「関数」
明らかに、オブジェクトが関数であるかどうかをテストしたい場合、typeof メソッドを使用しても、本当の意味でのテスト結果は保証されません。次に、すべてのブラウザでテスト結果を保証するソリューションが必要になります。関数自体には apply() と call() という 2 つのメソッドがあることがわかっていますが、これら 2 つのメソッドは IE の問題のある関数には存在しません。次のテストを試してください。
アラート(ドキュメントの種類.getElementsByTagName("本文")[0].getAttribute.call)
//IEでは結果は「未定義」となる
明らかに、これら 2 つの方法を利用することはできません。
2. 完璧なソリューションと実装プロセス
John Resig は、オブジェクトが関数であるかどうかを判断するための、この複雑だが安定した方法を次のように提供してくれました。
関数 isFunction( fn ) {
return !!fn && !fn.nodeName && fn.constructor != 文字列 &&
fn.constructor != RegExp && fn.constructor != 配列 &&
/function/i.test( fn + "" );
}
この関数は、まずテスト オブジェクトが存在することを確認し、それを「関数」を含む文字列にシリアル化します。これが検出の基礎になります (fn.constructor != String、fn.constructor != Array、および fn.constructor != RegExp)。 。さらに、宣言された関数が DOM ノード (fn.nodeName) ではないことを確認する必要があります。次に、toString テストを実行できます。関数を文字列に変換すると、ブラウザで (fn+"") すると、「関数名(){...}」のような結果が得られます。これが関数であるかどうかを判断するのは、文字列に「関数」という単語が含まれているかどうかを確認するのと同じくらい簡単です。これは驚くべきことに機能し、問題のどの関数についても、すべてのブラウザで必要な結果が得られます。従来の方法と比較すると、この関数の実行速度はやや遅いため、控えめに使用することをお勧めします。
John Resigは jQuery ライブラリの開発者であり、このライブラリを使用している友人はその簡潔な構文と優れたパフォーマンスをよく知っていると思います。コードのシンプルさと高性能を追求するだけでなく、作者の完璧主義の精神も印象的です。あなたが完璧主義者であれば、この記事は役に立つと思います。