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.toStringecma-international.org/ecma-262/6.0/….constructorpropiedad en su lugar.Respuestas:
Uso
instanceofpara tipos personalizados:Uso
typeofpara tipos integrados simples:Uso
instanceofpara 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
instanceofporque 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
instanceofno se puede comparar con los tipos primitivos, typeof can.undefined instanceof Objectdevuelve false y no produce una excepción. No sé qué tan reciente es ese cambio, pero lo haceinstanceofmás atractivo.undefined instanceof Objectno arroja una excepción porque, eh,undefinedestá 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].Arrayregresaráfalse, porqueArray.prototype !== window.frames[0].Arrayy 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 constructorEsto es incorrecto.o instanceof Cdevolverá 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 estruela primera vez, ¡perofalsecada 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
instanceofTambién funciona cuandocallbackes un subtipo deFunction, creofuente
instanceofen 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
instanceofno funcionará para primitivas, por ejemplo"foo" instanceof String, volveráfalsemientrastypeof "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.
instanceOfNo 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
instanceofpara verificar una función.fuente
typeofes incorrecto,fes todo lo siguiente: unObject(un objeto) y unaFunction(una función). Excepto para mí, tiene más sentido usarloinstanceofporque 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 detypeofesofes un hecho,objectno tengo idea de que también es una función.length,nameycallde Function, pero todos están extintos. Lo que es peor, no puede ser llamado y elTypeErrordice que:f is not a function.Diferencia práctica significativa:
No me preguntes por qué.
fuente
strhay 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
typeofes más rápido queinstanceofen situaciones donde ambos son aplicables.Dependiendo de su motor, la diferencia de rendimiento a favor
typeofpodría ser de alrededor del 20% . ( Su kilometraje puede variar )Aquí hay una prueba de referencia para
Array:Resultado
fuente
instanceofsiempre sigue la cadena de prototipos del objeto, por lo que la penalización de rendimiento dependerá de hasta qué punto en la cadena de prototiposinstanceofse 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 SomeClassytypeof 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
.constructoren todas partes.TL; DR: en situaciones en las
typeofque no es una opción, y cuando sabe que no le importa la cadena de prototipos ,Object.prototype.constructorpuede 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
nulloundefined: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. Contypeofusted 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 declarationy Function Constructor . Veremos cómotypeofy cómo seinstanceofcomporta 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,
typeofpodemos entender que es una función.typeofPorque 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 .MyFuncCallCrear función utilizando el constructor de funciones:
Aquí se
typeofafirma queMyFunc2es una función así como elinstanceofoperador. Ya sabemostypeofverificar si seMyFunc2implementó elCallmétodo o no. ComoMyFunc2es una función e implementa uncallmétodo, así es como setypeofsabe que es una función. Por otro lado, solíamosfunction constructorcrearloMyFunc2. se convierte en una instancia de.Function constructorPor esoinstanceoftambién se resuelvetrue.¿Qué es más seguro de usar?
Como podemos ver en ambos casos, el
typeofoperador puede afirmar con éxito que estamos tratando con una función aquí, es más seguro queinstanceof.instanceoffallará en caso defunction declarationporquefunction declarationsno 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) oobjecttipo.en el caso de objetos de nivel superior, como objetos integrados (String, Number, Boolean, Array ..) u objetos complejos o personalizados, todos ellos son de
objecttipo 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".
nulles un caso especial, que aparentemente es primitivo, pero de hecho es un caso especial para el objeto. Utilizandoa === nullpara comprobar nulo en su lugar.Por otro lado,
functiontambién es un caso especial, que es objeto incorporado perotypeofdevuelvefunctioncomo puede ver,
instanceofdebe pasar por la cadena de prototipos, mientras tanto,typeofsimplemente verifique el tipo de raíz una vez para que sea fácil de entender por quétypeofes más rápido queinstanceoffuente
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