Pregunta

He investigado un poco sobre esto, pero parece que los métodos utilizados son inconsistentes y variados.

Aquí hay algunos métodos que he usado en el pasado:

/* 1: */  typeof myFunc === 'function'
/* 2: */  myFunc.constructor === Function
/* 3: */  myFunc instanceof Function

Como parte de mi investigación, eché un vistazo a cómo algunas bibliotecas conocidas lograron esto:

 /* jQuery 1.2.6: */  !!fn && typeof fn != "string" && !fn.nodeName && fn.constructor != Array && /^[\s[]?function/.test( fn + "" )
 /* jQuery 1.3b1: */  toString.call(obj) === "[object Function]"
/* Prototype 1.6: */  typeof object == "function"
      /* YUI 2.6: */  typeof o === 'function'

Me sorprende que haya tantos métodos diferentes que utilizan los seres, ¿seguramente se ha acordado una única prueba aceptable? Y no tengo ni idea de cuáles eran las intenciones con la versión de jQuery 1.2.6, parece un poco exagerado ...

Por lo tanto, mi pregunta sigue siendo, ¿cuál es la mejor * forma de probar una función?

También agradecería conocer algunos de los métodos anteriores, especialmente jQuery 1.2.6. (Puedo ver lo que están haciendo, parece extraño)

[*] Por 'mejor', me refiero al método compatible con varios navegadores más aceptado.


EDITAR: Sí, ya sé que se ha discutido antes, pero todavía me gustaría hablar sobre el método más efectivo. ¿Por qué hay tantos métodos diferentes utilizados?

Las discusiones sobre SO hasta ahora solo han mencionado al operador de typeof (en su mayoría) pero nadie ha insinuado la eficacia de métodos alternativos.

¿Fue útil?

Solución

La mejor manera de probar si un objeto es una función es tipoof myFunc === 'function' . Si está utilizando una biblioteca, use la prueba de función de esa biblioteca: jQuery.isFunction (myFunc) .

Las cosas pueden ser reportadas erróneamente como funciones cuando se usa typeof . Esto es muy raro, pero hay una biblioteca para eliminar estas inconsistencias. jQuery trabajando en torno a estos problemas:

  • La función de informes de Firefox con typeof document.createElement (" object ")
  • Los informes de Safari funcionan con typeof document.body.childNodes
  • Las versiones anteriores de Firefox reportaban expresiones regulares como funciones (esto no es el caso en 3.0).
  • Se informa que algunas funciones globales integradas de IE ( alert ) y algunos métodos de nodo ( getAttribute ) son de tipo " objeto " ;.

El uso de instanceof en lugar de typeof evita algunos de estos. Por ejemplo, document.createElement (" object ") instanceof Function es false en Firefox.

Puede ver el nacimiento del primer método en los comentarios para el boleto original (# 3618) . El nuevo método es de changeset 5947 y parece haber sido inventado por Resig para resolver Fugas de memoria de IE . Probablemente sea más lento, pero más pequeño y más limpio.

No hay mucha diferencia entre == y === aquí en términos de cómo funcionan las cosas, pero la evaluación estricta es un poco más rápida y por lo tanto preferida.

Otros consejos

John Resig, el desarrollador de jQuery, parece haber tomado algunas decisiones extrañas en los aspectos internos de jQuery.

toString.call(obj) === "[object Function]"

se ve bastante limpio, pero no puedo pensar en ninguna situación en la que lo anterior sea cierto en el caso de que el enfoque typeof simple falle, pero quizás sepa algo que el resto de uso no.

typeof o === "function"

Iría con este último ya que tiene mayor claridad, a menos que tengas pruebas sólidas de que no funcionará.

¿Por qué usar la igualdad estricta en typeof ya que ambos operandos son cadenas? Estoy pasando por alto algún problema?

De todos modos, me gustaría la forma más simple de typeof, que parece que se está haciendo para eso y es legible. instanceof también se puede leer, pero parece insistir más en el hecho de que una función es un objeto, lo que podría ser irrelevante para el problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top