La instanceof
palabra clave en JavaScript puede ser bastante confusa cuando se encuentra por primera vez, ya que las personas tienden a pensar que JavaScript no es un lenguaje de programación orientado a objetos.
- ¿Qué es?
- ¿Qué problemas resuelve?
- ¿Cuándo es apropiado y cuándo no?
javascript
operators
instanceof
Alon Gubkin
fuente
fuente
"foo" instanceof String
=> falso,1 instanceof Number
=> falso,{} instanceof Object
=> falso. ¡¿Que qué?!"foo" instanceof String => false
es correcto, porquetypeof "foo" == 'string'
.new String("foo") instanceof String => true
, porquetypeof String == 'function'
- debe tratar la función como clase (definición de clase). La variable se convierte eninstanceof
algunafunction
(clase) cuando la asigna comovar v = new AnythingWhatTypeofEqualsFunction()
. Lo mismo se aplica a1
.typeof 1 == 'number'
- 'número' no es 'función' :) Siguiente -{} instanceof Object
estáTRUE
en nodos y navegadores modernos({}) instanceof Object
volverátrue
. De hecho, el código que escribió le dará un error.Respuestas:
en vez de
El operando del lado izquierdo (LHS) es el objeto real que se prueba con el operando del lado derecho (RHS) que es el constructor real de una clase. La definición básica es:
Aquí hay algunos buenos ejemplos y aquí hay un ejemplo tomado directamente del sitio de desarrolladores de Mozilla :
Una cosa que vale la pena mencionar es que se
instanceof
evalúa como verdadero si el objeto hereda del prototipo de la clase:Eso es
p instanceof Person
cierto ya quep
hereda dePerson.prototype
.Por solicitud del OP
He agregado un pequeño ejemplo con un código de muestra y una explicación.
Cuando declaras una variable, le das un tipo específico.
Por ejemplo:
Lo anterior se muestran algunas variables, a saber
i
,f
yc
. Los tipos soninteger
,float
y una definida por el usuarioCustomer
tipo de datos. Tipos como el anterior podrían ser para cualquier idioma, no solo JavaScript. Sin embargo, con JavaScript cuando declara una variable que no define explícitamente un tipovar x
, x podría ser un número / cadena / un tipo de datos definido por el usuario. Entonces, lo queinstanceof
hace es verificar el objeto para ver si es del tipo especificado, por lo que desde arribaCustomer
tomamos el objeto que podríamos hacer:Arriba hemos visto que
c
se declaró con el tipoCustomer
. Lo hemos renovado y comprobado si es de tipoCustomer
o no. Claro que es cierto. Luego, aún usando elCustomer
objeto, verificamos si es aString
. No, definitivamente noString
hemos renovado unCustomer
objeto, no unString
objeto. En este caso, devuelve falso.¡Es realmente así de simple!
fuente
color1 instanceof String;
esto devolverá verdadero porque color1 es una cadena.person p = new person()
p es ahora un tipo de persona y no un tipo de cadena.var zero = 0; alert(zero); zero = "0"; alert(zero)
pasamos de primitivoint
a primitivostring
sin ningún problema.int
a primitivostring
.Hay una faceta importante de la instancia que no parece estar cubierta en ninguno de los comentarios hasta el momento: la herencia. Una variable que se evalúa mediante el uso de instanceof podría ser verdadera para múltiples "tipos" debido a la herencia prototípica.
Por ejemplo, definamos un tipo y un subtipo:
Ahora que tenemos un par de "clases", hagamos algunas instancias y descubramos de qué son instancias:
¿Ves esa última línea? Todas las llamadas "nuevas" a una función devuelven un objeto que hereda de Object. Esto es válido incluso cuando se usa la creación abreviada de creación de objetos:
¿Y qué hay de las definiciones de "clase" en sí mismas? ¿De qué son instancias?
Creo que es importante comprender que cualquier objeto puede ser una instancia de MÚLTIPLES tipos, ya que usted (incorrectamente) supone que puede diferenciar entre, digamos y un objeto y una función mediante el uso de
instanceof
. Como este último ejemplo muestra claramente que una función es un objeto.Esto también es importante si está utilizando algún patrón de herencia y desea confirmar la progenie de un objeto mediante métodos distintos al tipeo de pato.
Espero que ayude a cualquiera a explorar
instanceof
.fuente
SubFoo.prototype = new Foo();
él, puede agregarle más métodos, y lasubfoo instanceof Foo
verificación aún pasará tan bien comosubfoo instanceof SubFoo
Las otras respuestas aquí son correctas, pero no entienden cómo
instanceof
funciona realmente, lo que puede ser de interés para algunos abogados de idiomas.Cada objeto en JavaScript tiene un prototipo, accesible a través de la
__proto__
propiedad. Las funciones también tienen unaprototype
propiedad, que es la inicial__proto__
de cualquier objeto creado por ellas. Cuando se crea una función, se le da un objeto único paraprototype
. Elinstanceof
operador utiliza esta singularidad para darle una respuesta. Asíinstanceof
se vería si lo escribiera como una función.Esto es básicamente parafraseando la edición 5.1 de ECMA-262 (también conocida como ES5), sección 15.3.5.3.
Tenga en cuenta que puede reasignar cualquier objeto a la
prototype
propiedad de una función , y puede reasignar la__proto__
propiedad de un objeto después de su construcción. Esto te dará algunos resultados interesantes:fuente
__proto__
propiedad " " no está permitida en IE. Si recuerdo correctamente, la manipulación directa de la propiedad tampoco está incluida en la especificación de ECMA, por lo que probablemente sea una mala idea usarla para tareas que no sean actividades académicas.Object.getPrototypeOf(o)
, será el mismo__proto__
que describe, pero se ajusta a ECMAScript.Creo que vale la pena señalar que la instancia de se define mediante el uso de la palabra clave "nueva" al declarar el objeto. En el ejemplo de JonH;
Lo que no mencionó es esto;
Especificar "nuevo" en realidad copió el estado final de la función del constructor de cadenas en el color1 var, en lugar de simplemente establecerlo en el valor de retorno. Creo que esto muestra mejor lo que hace la nueva palabra clave;
El uso de "new" asigna el valor de "this" dentro de la función a la var declarada, mientras que no usarlo asigna el valor de retorno en su lugar.
fuente
new
con ninguno de los tipos de JavaScript, lo que hace que la respuesta aceptada sea mucho más confusa para los principiantes.text = String('test')
yoptions = {}
no vamos a probarloinstanceof
, sino más bien contypeof
.Y puede usarlo para el manejo de errores y la depuración, como este:
fuente
fuente
Javascript es un lenguaje prototípico, lo que significa que utiliza prototipos para "herencia". el
instanceof
operador prueba si el tipo deprototype
propiedad de una función constructora está presente en la__proto__
cadena de un objeto. Esto significa que hará lo siguiente (suponiendo que testObj es un objeto de función):obj.__proto__ === testObj.prototype
>> si estotrue
instanceof
regresarátrue
.obj.__proto__.__proto__ === testObj.prototype
>> si esto estrue
instanceof
regresarátrue
.testObj.prototype
continuacióninstanceof
del operador regresaráfalse
.Ejemplo:
Solucionó el problema de verificar convenientemente si un objeto deriva de un cierto prototipo. Por ejemplo, cuando una función recibe un objeto que puede tener varios prototipos. Luego, antes de usar métodos de la cadena de prototipos, podemos usar el
instanceof
operador para verificar si estos métodos están en el objeto.Ejemplo:
Aquí en la
talk()
función primero se verifica si el prototipo se encuentra en el objeto. Después de esto, se elige el método apropiado para ejecutar. Si no se realiza esta comprobación, se podría ejecutar un método que no existe y, por lo tanto, un error de referencia.Ya hemos repasado esto. Úselo cuando necesite verificar el prototipo de un objeto antes de hacer algo con él.
fuente
PersonX.prototype.talk
, de modo que latalk
función pueda simplemente funcionarperson.talk()
.__proto__
en la documentación, está en desuso - escriba en suObject.getPrototype()
lugarSobre la pregunta "¿Cuándo es apropiado y cuándo no?", Mis 2 centavos:
instanceof
rara vez es útil en el código de producción, pero es útil en las pruebas en las que desea afirmar que su código devuelve / crea objetos del tipo correcto. Al ser explícito sobre los tipos de objetos que devuelve / crea su código, sus pruebas se vuelven más poderosas como una herramienta para comprender y documentar su código.fuente
instanceof
es solo azúcar sintáctico paraisPrototypeOf
:instanceof
solo depende del prototipo de un constructor de un objeto.Un constructor es solo una función normal. Estrictamente hablando, es un objeto de función, ya que todo es un objeto en Javascript. Y este objeto de función tiene un prototipo, porque cada función tiene un prototipo.
Un prototipo es solo un objeto normal, que se encuentra dentro de la cadena de prototipo de otro objeto. Eso significa que estar en la cadena de prototipo de otro objeto convierte un objeto en un prototipo:
El
instanceof
operador debe evitarse porque falsifica clases, que no existen en Javascript. A pesar de que laclass
palabra clave tampoco está en ES2015, yaclass
que nuevamente es solo azúcar sintáctica para ... pero esa es otra historia.fuente
instanceof
se deriva deisPrototypeOf
. Yo llamo a esto azúcar sintáctico. Y tu fuente de MDN es una broma, ¿no?instanceof
no hace lo mismo queisPrototypeOf
. Eso es.Acabo de encontrar una aplicación del mundo real y la usaré con más frecuencia ahora, creo.
Si usa eventos jQuery, a veces desea escribir una función más genérica que también se puede llamar directamente (sin evento). Puede usar
instanceof
para verificar si el primer parámetro de su función es una instancia dejQuery.Event
y reacciona adecuadamente.En mi caso, la función necesitaba calcular algo para todos (mediante un evento de clic en un botón) o solo un elemento específico. El código que usé:
fuente