Pour juger du type de fonction, nous utilisons généralement la méthode typeof. Dans des circonstances normales, elle obtiendra l'effet attendu. Cependant, certains détails ne nous sont pas bien connus. Après avoir analysé ces détails, John Resig nous a fourni une solution parfaite, qui sera présentée en détail dans cet article :
1. Détails inconnus des méthodes traditionnelles
Il ne fait aucun doute que pour déterminer le type de fonction, nous utilisons la méthode typeof, telle que :
fonction fn(){
//contenu
}
alert(typeof fn)//Le résultat est "fonction".
Cependant, cette méthode ne fonctionne pas comme prévu dans certains navigateurs.
1. Firefox2 et Firefox3
Dans ces deux navigateurs, l'utilisation de typeof pour détecter le type d'un élément d'objet HTML entraîne un résultat "fonction" imprécis au lieu d'un "objet", tel que HTMLDocument. comme:
alert (type de document HTML);
//Dans Firefox2, le résultat est « fonction » ;
//Dans Firefox3, le résultat est « objet » ;
2. Firefox2
Pour les expressions régulières, le résultat renvoyé dans ce navigateur est « fonction » (le résultat est « objet » dans Firefox3), tel que :
var reg = /test/;
alert (type d'enregistrement);
//Dans Firefox2, le résultat est « fonction » ;
//Dans Firefox3, le résultat est « objet » ;
Remarque : je l'ai testé dans Safari, et le résultat était également "fonction".
3. IE6 et IE7
Lorsque vous utilisez la méthode typeof sur un élément DOM dans IE, le résultat est « objet ». comme:
alert(typeof document.getElementsByTagName("body")[0].getAttribute);
//Le résultat est "objet"
4. Safari3
Safari pense que la NodeList des éléments DOM est une fonction, telle que :
alert(type de document.body.childNodes);
//Le résultat est "fonction"
Évidemment, si vous souhaitez tester si un objet est une fonction, l'utilisation de la méthode typeof ne garantit pas le résultat du test dans un sens réel. Ensuite, nous avons besoin d’une solution garantissant les résultats des tests dans tous les navigateurs. Nous savons que la fonction elle-même a deux méthodes, apply() et call(), mais ces deux méthodes n'existent pas dans la fonction problématique dans IE. Essayez le test suivant :
alert(typede document.getElementsByTagName("body")[0].getAttribute.call)
//Le résultat est "indéfini" dans IE
Évidemment, on ne peut pas profiter de ces deux méthodes.
2. Solution parfaite et processus de mise en œuvre
John Resig nous a fourni une solution parfaite. Cette méthode complexe mais stable pour déterminer si un objet est une fonction est la suivante :
la fonction estFonction(fn) {
return !!fn && !fn.nodeName && fn.constructor != String &&
fn.constructor != RegExp && fn.constructor != Tableau &&
/function/i.test( fn + "" );
}
Cette fonction garantit d'abord que l'objet de test existe et le sérialise dans une chaîne contenant "function". C'est la base de notre détection (fn.constructor != String, fn.constructor != Array et fn.constructor != RegExp ). . De plus, nous devons nous assurer que la fonction déclarée n'est pas un nœud DOM (fn.nodeName). Ensuite, nous pouvons faire le test toString. Si nous convertissons une fonction en chaîne, dans un navigateur (fn+"") nous donne le résultat comme ceci "nom de fonction(){...}". Désormais, déterminer s'il s'agit d'une fonction est aussi simple que de vérifier si la chaîne contient le mot « fonction ». Cela fait des merveilles, pour n'importe quelle fonction en question, nous obtenons les résultats dont nous avons besoin dans tous les navigateurs. Par rapport à la méthode traditionnelle, la vitesse d’exécution de cette fonction est quelque peu insatisfaisante. L’auteur recommande de l’utiliser avec prudence.
John Resig est le développeur de la bibliothèque jQuery, je pense que les amis qui utilisent cette bibliothèque connaissent sa syntaxe concise et ses excellentes performances. En plus de rechercher la simplicité du code et les hautes performances, l'esprit de perfection de l'auteur est également impressionnant. Si vous êtes perfectionniste, je pense que cet article vous sera utile.
Texte original : http://www.denisdeng.com/?p=426