Al juzgar el tipo de función, generalmente usamos el método typeof. En circunstancias normales, obtendrá el efecto que esperábamos. Sin embargo, hay algunos detalles que no conocemos bien. Después de analizar estos detalles, John Resig nos brindó una solución perfecta, que se presentará en detalle en este artículo:
1. Detalles desconocidos de los métodos tradicionales.
No hay duda de que al determinar el tipo de función utilizamos el método typeof, como por ejemplo:
función fn(){
//contenido
}
alerta (tipo de fn) // El resultado es "función".
Sin embargo, este método no funciona como se esperaba en algunos navegadores.
1. Firefox2 y Firefox3
En estos dos navegadores, el uso de typeof para detectar el tipo de un elemento de objeto HTML da como resultado un resultado de "función" impreciso en lugar de "objeto", como HTMLDocument. como:
alerta (tipo de documento HTML);
//En Firefox2 el resultado es "función";
//En Firefox3 el resultado es "objeto";
2. Firefox2
Para las expresiones regulares, el resultado devuelto en este navegador es "función" (el resultado es "objeto" en Firefox3), como por ejemplo:
var reg = /prueba/;
alerta (tipo de registro);
//En Firefox2 el resultado es "función";
//En Firefox3 el resultado es "objeto";
Nota: lo probé en Safari y el resultado también fue "función".
3. IE6 e IE7
Cuando se utiliza el método typeof en un elemento DOM en IE, el resultado es "objeto". como:
alerta(tipo de documento.getElementsByTagName("cuerpo")[0].getAttribute);
//El resultado es "objeto"
4. Safari 3
Safari cree que la NodeList de elementos DOM es una función, como por ejemplo:
alerta (tipo de documento.body.childNodes);
//El resultado es "función"
Obviamente, si desea probar si un objeto es una función, utilizar el método typeof no garantiza el resultado de la prueba en un sentido real. Entonces, necesitamos una solución que garantice los resultados de las pruebas en todos los navegadores. Sabemos que la función en sí tiene dos métodos, aplicar() y llamar(), pero estos dos métodos no existen en la función problemática en IE. Pruebe la siguiente prueba:
alerta(tipo de documento.getElementsByTagName("cuerpo")[0].getAttribute.call)
//El resultado es "indefinido" en IE
Evidentemente, no podemos aprovechar estos dos métodos.
2. Solución perfecta y proceso de implementación.
John Resig nos proporcionó una solución perfecta. Este método complejo pero estable para determinar si un objeto es una función es el siguiente:
la función esFunción( fn ) {
retorno !!fn && !fn.nodeName && fn.constructor != Cadena &&
fn.constructor!= RegExp && fn.constructor!= Matriz &&
/función/i.test( fn + "" );
}
Esta función primero garantiza que el objeto de prueba existe y lo serializa en una cadena que contiene "función". Esta es la base de nuestra detección (fn.constructor! = String, fn.constructor! = Array y fn.constructor! = RegExp). . Además, debemos asegurarnos de que la función declarada no sea un nodo DOM (fn.nodeName). Luego, podemos hacer la prueba toString. Si convertimos una función a una cadena, en un navegador (fn+"") nos da el resultado así "nombre de función(){...}". Ahora bien, determinar si se trata de una función es tan sencillo como comprobar si la cadena contiene la palabra "función". Esto funciona de maravilla, para cualquier función en cuestión, obtenemos los resultados que necesitamos en todos los navegadores. En comparación con el método tradicional, la velocidad de ejecución de esta función es algo insatisfactoria. El autor recomienda que la utilicemos de forma conservadora.
John Resig es el desarrollador de la biblioteca jQuery. Creo que los amigos que usan esta biblioteca están familiarizados con su sintaxis concisa y su excelente rendimiento. Además de buscar la simplicidad del código y el alto rendimiento, el espíritu de perfección del autor también es impresionante. Si eres un perfeccionista, creo que este artículo te será útil.
Texto original: http://www.denisdeng.com/?p=426