2010-12-03 13 views
13

Esta es probablemente una pregunta estúpida, así que por favor, quédate conmigo.Uso de toString() en lugar de constructor en JavaScript

¿Por qué veo tantos ejemplos que prueban si un objeto es una Función comparando su toString() con "[objeto Función]"?

Por ejemplo:

function isFunction(obj) { 
    return Object.prototype.toString.call(obj) == "[object Function]"; 
} 

¿No podemos usar instanceof Function o obj.constructor === Function? ¿No son compatibles entre navegadores?

parece ineficaz, pero ¿verdad? ¿Por qué?

+0

posible duplicado de [isFunction y InternetExplorer de jQuery] (http://stackoverflow.com/questions/3514336/jquerys-isfunction-and-internetexplorer) –

Respuesta

7

La respuesta corta se debe a que typeof /foo/ es una función de los navegadores Webkit. CMS tiene la explicación prolongado @jQuery's isFunction and InternetExplorer

Y instanceOf no es fiable porque como señala Zuriy: surgen

Los problemas cuando se trata de secuencias de comandos en entornos multi-frame DOM. En pocas palabras, los objetos Array creados dentro de un iframe no comparten [[Prototype]] con arreglos creados dentro de otro iframe. Sus constructores son objetos diferentes y, por lo tanto, fallan las verificaciones instanceof y constructor:

Artículo excelente @http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ de Zuriy sobre el tema.

Ejemplo tomado del artículo:

var iframe = document.createElement('iframe'); 
document.body.appendChild(iframe); 
xArray = window.frames[window.frames.length-1].Array; 
var arr = new xArray(1,2,3); // [1,2,3] 

// Boom! 
arr instanceof Array; // false 

// Boom! 
arr.constructor === Array; // false 
+0

cuando/por qué no es instanciaDefiable? – Matt

+0

Puedo ver por qué "instanceOf" es malo, pero ¿qué pasa con el uso de "obj.constructor". ¿Podemos obtener un ejemplo? –

+0

@meder ¡gracias! No tenía ni idea. – Matt

1

No están probando su método toString, están llamando al método toString del prototipo de Object en obj para convertirlo en una cadena. Una función arroja como '[objeto Función]' a una cadena.

instanceof no es confiable y tampoco es el modo constructor. El constructor requiere una comprobación para ver si obj es nulo o no antes de intentar acceder a su propiedad de constructor; también supongo que es un poco más lento que el método toString.

+0

I puede ver ¿Por qué "instanceof" no es confiable (ejemplo de función Array() {}), pero donde fallaría "constructor"? –

+1

@Eric por exactamente la misma razón que "instanceof" es un problema: la referencia "constructor" sería diferente para los objetos de dos marcos diferentes, incluso si fueron construidos por la "misma" función, porque cada * instancia * del la función del constructor (en cada ventana separada) es distinta. – Pointy

Cuestiones relacionadas