En mi caso particular:
callback instanceof Function
o
typeof callback == "function"
¿importa, cuál es la diferencia?
Recurso adicional:
JavaScript-Garden typeof vs instanceof
javascript
instanceof
typeof
farinspace
fuente
fuente
Object.prototype.toString
ecma-international.org/ecma-262/6.0/….constructor
propiedad en su lugar.Respuestas:
Uso
instanceof
para tipos personalizados:Uso
typeof
para tipos integrados simples:Uso
instanceof
para tipos integrados complejos:Y el último es un poco complicado:
fuente
Use instanceof for complex built in types
- Esto sigue siendo propenso a errores. Es mejor usar ES5Array.isArray()
et al. o las cuñas recomendadas.Ambas son similares en funcionalidad porque ambas devuelven información de tipo, sin embargo, personalmente prefiero
instanceof
porque compara tipos reales en lugar de cadenas. La comparación de tipos es menos propensa a errores humanos, y es técnicamente más rápida ya que compara punteros en la memoria en lugar de hacer comparaciones de cadenas completas.fuente
Una buena razón para usar typeof es si la variable puede estar indefinida.
Una buena razón para usar instanceof es si la variable puede ser nula.
Entonces, en mi opinión, dependería de qué tipo de datos posibles esté verificando.
fuente
instanceof
no se puede comparar con los tipos primitivos, typeof can.undefined instanceof Object
devuelve false y no produce una excepción. No sé qué tan reciente es ese cambio, pero lo haceinstanceof
más atractivo.undefined instanceof Object
no arroja una excepción porque, eh,undefined
está definido. La constante existe en el espacio de nombres. Cuando no existe una variable (debido a un error tipográfico, por ejemplo), instanceof generará una excepción. El uso de typeof en una variable no existente produce 'undefined' por otro lado.Para aclarar las cosas, necesita conocer dos hechos:
Object.setPrototypeOf()
método (ECMAScript 2015) o por la__proto__
propiedad (navegadores antiguos, obsoletos). Sin embargo, no se recomienda cambiar el prototipo de un objeto debido a problemas de rendimiento.Por lo tanto, instanceof es aplicable solo a objetos. En la mayoría de los casos, no está utilizando constructores para crear cadenas o números. Usted puede. Pero casi nunca lo haces.
También instanceof no puede verificar, exactamente qué constructor se usó para crear el objeto, pero devolverá verdadero, incluso si el objeto se deriva de la clase que se está verificando. En la mayoría de los casos, este es el comportamiento deseado, pero a veces no lo es. Entonces debes mantener esa mente.
Otro problema es que diferentes ámbitos tienen diferentes entornos de ejecución. Esto significa que tienen diferentes incorporados (diferentes objetos globales, diferentes constructores, etc.). Esto puede dar lugar a resultados inesperados.
Por ejemplo,
[] instanceof window.frames[0].Array
regresaráfalse
, porqueArray.prototype !== window.frames[0].Array
y las matrices heredan de la primera.Además, no se puede usar con un valor indefinido, porque no tiene un prototipo.
Ahora hablemos de una cosa difícil. ¿Qué pasa si usa el constructor para crear un tipo primitivo?
Parece magia. Pero no lo es. Se llama boxeo (envolver el valor primitivo por objeto) y desempaquetar (extraer el valor primitivo envuelto del objeto). Este tipo de código parece ser "un poco" frágil. Por supuesto, puede evitar crear tipos primitivos con constructores. Pero hay otra situación posible, cuando el boxeo puede golpearte. Cuando usa Function.call () o Function.apply () en un tipo primitivo.
Para evitar esto, puede usar el modo estricto:
upd: desde ECMAScript 2015, hay un tipo más llamado Symbol, que tiene su propio typeof == "symbol" .
Usted puede leer sobre él en MDN: ( Símbolo , typeof ).
fuente
if an object is created by a given constructor
Esto es incorrecto.o instanceof C
devolverá verdadero si o hereda de C.prototype. Usted ha mencionado algo sobre esto más adelante en su respuesta, pero no está muy claro.Descubrí algunos comportamientos realmente interesantes (leídos como "horribles") en Safari 5 e Internet Explorer 9. Estaba usando esto con gran éxito en Chrome y Firefox.
Luego pruebo en IE9, y no funciona en absoluto. Gran sorpresa. Pero en Safari, ¡es intermitente! Así que empiezo a depurar y encuentro que Internet Explorer siempre regresa
false
. Pero lo más extraño es que Safari parece estar haciendo algún tipo de optimización en su máquina virtual JavaScript, donde estrue
la primera vez, ¡perofalse
cada vez que presionas recargar!Mi cerebro casi explotó.
Así que ahora me he decidido por esto:
Y ahora todo funciona muy bien. Tenga en cuenta que puede llamar
"a string".toString()
y solo devuelve una copia de la cadena, es decirAsí que usaré ambos de ahora en adelante.
fuente
Otras diferencias prácticas significativas:
fuente
instanceof
También funciona cuandocallback
es un subtipo deFunction
, creofuente
instanceof
en Javascript puede ser escamoso: creo que los marcos principales intentan evitar su uso. Diferentes ventanas es una de las formas en que puede romperse: creo que las jerarquías de clase también pueden confundirlo.Hay mejores formas de probar si un objeto es un cierto tipo incorporado (que generalmente es lo que desea). Cree funciones de utilidad y úselas:
Y así.
fuente
instanceof
no funcionará para primitivas, por ejemplo"foo" instanceof String
, volveráfalse
mientrastypeof "foo" == "string"
que volverátrue
.Por otro lado
typeof
, probablemente no haga lo que quiere cuando se trata de objetos personalizados (o clases, como quiera llamarlos). Por ejemplo:Sucede que las funciones son primitivas de 'función' e instancias de 'Función', lo cual es un poco extraño dado que no funciona así para otros tipos primitivos, por ejemplo.
pero
fuente
Recomendaría usar prototipos
callback.isFunction()
.Han descubierto la diferencia y puedes contar con su razón.
Supongo que otros frameworks JS también tienen esas cosas.
instanceOf
No funcionaría en funciones definidas en otras ventanas, creo. Su función es diferente a la tuyawindow.Function
.fuente
Al verificar una función, siempre se debe usar
typeof
.Aquí está la diferencia:
Es por eso que uno nunca debe usar
instanceof
para verificar una función.fuente
typeof
es incorrecto,f
es todo lo siguiente: unObject
(un objeto) y unaFunction
(una función). Excepto para mí, tiene más sentido usarloinstanceof
porque sabiendo que es una función, sé que también es un objeto, ya que todas las funciones son objetos en ECMAScript. Lo contrario no es cierto: saber a partir detypeof
esof
es un hecho,object
no tengo idea de que también es una función.length
,name
ycall
de Function, pero todos están extintos. Lo que es peor, no puede ser llamado y elTypeError
dice que:f is not a function
.Diferencia práctica significativa:
No me preguntes por qué.
fuente
str
hay una cadena primitiva, no un objeto de cadena. Lo mismo ocurre con las primitivas de números y las primitivas booleanas, no son instancias de sus contrapartes "construidas", los objetos String, Number y Boolean. JavaScript convierte automáticamente estas tres primitivas en objetos cuando es necesario (como utilizar un método en la cadena de prototipos del objeto). En el otro lado de su diferencia práctica, instanceof es mejor para verificar matrices desde entoncestypeof [] == "object" // true
.Actuación
typeof
es más rápido queinstanceof
en situaciones donde ambos son aplicables.Dependiendo de su motor, la diferencia de rendimiento a favor
typeof
podría ser de alrededor del 20% . ( Su kilometraje puede variar )Aquí hay una prueba de referencia para
Array
:Resultado
fuente
instanceof
siempre sigue la cadena de prototipos del objeto, por lo que la penalización de rendimiento dependerá de hasta qué punto en la cadena de prototiposinstanceof
se pruebe la clase . Entonces, para una cadena de herencia corta, la penalización será menor (como[] instanceof Array
,,{} instanceof Object
) y por mucho tiempo, mayor. Por lo tanto, si ambosobj instanceof SomeClass
ytypeof obj !== 'string'
significa lo mismo desde la perspectiva de su código de alguna hipotética (Fe Si sólo hacer una prueba enif
, y noswitch
-ing a través de múltiples clases, etc.), entonces sería mejor elegir un segundo, en cuanto al rendimiento,Esto es sólo el conocimiento complementario a todas las otras explicaciones - estoy no sugiriendo utilizar
.constructor
en todas partes.TL; DR: en situaciones en las
typeof
que no es una opción, y cuando sabe que no le importa la cadena de prototipos ,Object.prototype.constructor
puede ser una alternativa viable o incluso mejor queinstanceof
:Ha estado en el estándar desde 1.1, por lo que no se preocupe por la compatibilidad con versiones anteriores.
Muhammad Umer mencionó brevemente esto en un comentario en algún lugar aquí también. Funciona en todo con un prototipo, por lo que no todo
null
oundefined
:Además, dependiendo de su caso de uso, puede ser mucho más rápido que
instanceof
(la razón probablemente sea que no tiene que verificar toda la cadena del prototipo). En mi caso, necesitaba una forma rápida de verificar si un valor es una matriz escrita:https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
Y los resultados:
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
Por curiosidad, hice una referencia rápida de juguete en contra
typeof
; Sorprendentemente no funciona mucho peor, y parece incluso un poco más rápido en Chrome:https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
NOTA: ¡El orden en que se enumeran las funciones cambia entre imágenes!
Chrome 64.0.3282.167 (64 bits, Windows)
Firefox 59.0b10 (64 bits, Windows)
NOTA: ¡El orden en que se enumeran las funciones cambia entre imágenes!
fuente
Use instanceof porque si cambia el nombre de la clase obtendrá un error de compilación.
fuente
fuente
Viniendo de una estricta educación OO, iría por
Las cadenas son propensas a mi horrible ortografía u otros errores tipográficos. Además, siento que se lee mejor.
fuente
A pesar de que instanceof puede ser un poco más rápido que typeof , prefiero el segundo debido a tal magia posible:
fuente
Un caso más es que solo puedes cotejar
instanceof
, devuelve verdadero o falso. Contypeof
usted puede obtener el tipo de algo proporcionadofuente
teniendo en cuenta el rendimiento, será mejor que use typeof con un hardware típico, si crea un script con un bucle de 10 millones de iteraciones, la instrucción: typeof str == 'string' tomará 9 ms, mientras que 'string' instancia de String tomará 19 ms
fuente
¡Por supuesto que importa ........!
Veamos esto con ejemplos. En nuestro ejemplo, declararemos la función de dos maneras diferentes.
Usaremos ambos
function declaration
y Function Constructor . Veremos cómotypeof
y cómo seinstanceof
comporta en esos dos escenarios diferentes.Crear función utilizando la declaración de función:
Una posible explicación para un resultado tan diferente es que, como hicimos una declaración de función,
typeof
podemos entender que es una función.typeof
Porque verifica si la expresión en la que se opera typeof, en nuestro caso, implementó el método de llamada o no . Si implementa el método, es una función. De lo contrario, no. Para aclaraciones, verifique la especificación ecmascript para typeof .MyFunc
Call
Crear función utilizando el constructor de funciones:
Aquí se
typeof
afirma queMyFunc2
es una función así como elinstanceof
operador. Ya sabemostypeof
verificar si seMyFunc2
implementó elCall
método o no. ComoMyFunc2
es una función e implementa uncall
método, así es como setypeof
sabe que es una función. Por otro lado, solíamosfunction constructor
crearloMyFunc2
. se convierte en una instancia de.Function constructor
Por esoinstanceof
también se resuelvetrue
.¿Qué es más seguro de usar?
Como podemos ver en ambos casos, el
typeof
operador puede afirmar con éxito que estamos tratando con una función aquí, es más seguro queinstanceof
.instanceof
fallará en caso defunction declaration
porquefunction declarations
no son una instancia deFunction constructor
.Mejores prácticas :
Como sugirió Gary Rafferty , la mejor manera debería ser usar ambos tipos y instancias juntos.
fuente
Para ser muy preciso , se debe utilizar instancia de donde el valor se crea a través del constructor (generalmente tipos personalizados), por ejemplo
mientras que typeof para verificar valores creados solo por asignaciones para, por ejemplo,
fuente
no es necesario abrumarse con la tonelada de ejemplos anteriores, solo tenga en cuenta dos puntos de vista:
typeof var;
es un operador unario que devolverá el tipo original o el tipo raíz de var. de modo que le proporcione los tipos primitivos (string
,number
,bigint
,boolean
,undefined
, ysymbol
) oobject
tipo.en el caso de objetos de nivel superior, como objetos integrados (String, Number, Boolean, Array ..) u objetos complejos o personalizados, todos ellos son de
object
tipo raíz, pero el tipo de instancia basado en ellos es variable (como la clase OOP concepto de herencia), aquía instanceof A
, un operador binario, lo ayudará, pasará por la cadena de prototipo para verificar si el constructor del operando correcto (A) aparece o no.así que cada vez que quiera marcar "tipo raíz" o trabajar con una variable primitiva, use "typeof", de lo contrario use "instanceof".
null
es un caso especial, que aparentemente es primitivo, pero de hecho es un caso especial para el objeto. Utilizandoa === null
para comprobar nulo en su lugar.Por otro lado,
function
también es un caso especial, que es objeto incorporado perotypeof
devuelvefunction
como puede ver,
instanceof
debe pasar por la cadena de prototipos, mientras tanto,typeof
simplemente verifique el tipo de raíz una vez para que sea fácil de entender por quétypeof
es más rápido queinstanceof
fuente
Según la documentación de MDN sobre typeof , los objetos instanciados con la palabra clave "nueva" son del tipo 'objeto':
Mientras que la documentación sobre la instancia de puntos que:
Entonces, si uno quiere verificar, por ejemplo, que algo es una cadena, sin importar cómo se creó, el enfoque más seguro sería usar
instanceof
.fuente