¿Hay un JavaScript equivalente de Java s' class.getName()?
javascript
Ewen Cartwright
fuente
fuente

Respuestas:
No se .
Actualización de ES2015 : el nombre de
class Foo {}esFoo.name. El nombre dethingla clase, independientemente delthingtipo, esthing.constructor.name. Los constructores incorporados en un entorno ES2015 tienen lanamepropiedad correcta ; por ejemplo(2).constructor.namees"Number".Pero aquí hay varios hacks que se caen de una forma u otra:
Aquí hay un truco que hará lo que necesita: tenga en cuenta que modifica el prototipo del Objeto, algo que la gente desaprueba (generalmente por una buena razón)
Ahora, todos sus objetos tendrán la función
getName(), que devolverá el nombre del constructor como una cadena. He probado estoFF3yIE7no puedo hablar de otras implementaciones.Si no desea hacer eso, aquí hay una discusión sobre las diversas formas de determinar los tipos en JavaScript ...
Recientemente actualicé esto para que sea un poco más exhaustivo, aunque difícilmente sea eso. Correcciones bienvenidas ...
Usando la
constructorpropiedad ...Cada uno
objecttiene un valor para suconstructorpropiedad, pero dependiendo de cómoobjectse construyó y de qué quiere hacer con ese valor, puede ser útil o no.En términos generales, puede usar la
constructorpropiedad para probar el tipo de objeto de la siguiente manera:Entonces, eso funciona lo suficientemente bien para la mayoría de las necesidades. Dicho eso ...
Advertencias
No funciona en absoluto en muchos casos
Este patrón, aunque roto, es bastante común:
Objectsconstruido víanew Thingytendrá unaconstructorpropiedad que apunta aObject, noThingy. Entonces caemos desde el principio; simplemente no puedes confiarconstructoren una base de código que no controlas.Herencia múltiple
Un ejemplo en el que no es tan obvio es usar la herencia múltiple:
Las cosas ahora no funcionan como es de esperar que:
Por lo tanto, puede obtener resultados inesperados si la
objectprueba tiene unobjectconjunto diferente como talprototype. Hay formas de evitar esto fuera del alcance de esta discusión.Hay otros usos para la
constructorpropiedad, algunos interesantes, otros no tanto; por ahora no profundizaremos en esos usos ya que no es relevante para esta discusión.No funcionará entre marcos y ventanas cruzadas
El uso
.constructorpara la verificación de tipo se interrumpirá cuando desee verificar el tipo de objetos que provienen de diferenteswindowobjetos, por ejemplo, de un iframe o una ventana emergente. Esto se debe a que hay una versión diferente de cada tipo de núcleoconstructoren cada 'ventana', es decirUsar el
instanceofoperador ...El
instanceofoperador también es una forma limpia de probar elobjecttipo, pero tiene sus propios problemas potenciales, al igual que laconstructorpropiedad.Pero
instanceofno funciona para valores literales (porque los literales no lo sonObjects)Los literales deben estar envueltos en un
Objectparainstanceofque funcionen, por ejemploLa
.constructorcomprobación funciona bien para los literales porque la.invocación del método envuelve implícitamente los literales en su tipo de objeto respectivo¿Por qué dos puntos para los 3? Porque Javascript interpreta el primer punto como un punto decimal;)
No funcionará entre marcos y ventanas cruzadas
instanceoftampoco funcionará en diferentes ventanas, por la misma razón que laconstructorverificación de propiedad.Usar la
namepropiedad de laconstructorpropiedad ...No funciona en absoluto en muchos casos
De nuevo, ver arriba; Es bastante común
constructorque esté completamente equivocado e inútil.NO funciona en <IE9
El uso
myObjectInstance.constructor.namele dará una cadena que contiene el nombre de laconstructorfunción utilizada, pero está sujeta a las advertencias sobre laconstructorpropiedad que se mencionó anteriormente.Para IE9 y superior, puede parchear en soporte :
Versión actualizada del artículo en cuestión. Esto se agregó 3 meses después de que se publicó el artículo, esta es la versión recomendada para usar por el autor del artículo Matthew Scharley. Este cambio se inspiró en los comentarios que señalaban posibles dificultades en el código anterior.
Usando Object.prototype.toString
Resulta que, como se detalla en esta publicación , puede usar
Object.prototype.toStringla implementación genérica y de bajo nivel detoStringpara obtener el tipo para todos los tipos integradosSe podría escribir una función auxiliar breve como
para eliminar el cruft y obtener solo el nombre del tipo
Sin embargo, regresará
Objectpara todos los tipos definidos por el usuario.Advertencias para todos ...
Todos estos están sujetos a un problema potencial, y esa es la cuestión de cómo se construyó el objeto en cuestión. Aquí hay varias formas de construir objetos y los valores que devolverán los diferentes métodos de verificación de tipos:
Si bien no todas las permutaciones están presentes en este conjunto de ejemplos, es de esperar que haya suficientes para darle una idea acerca de lo desordenado que podrían ser las cosas según sus necesidades. No asumas nada, si no entiendes exactamente lo que estás buscando, puedes terminar con el descifrado del código donde no esperas que lo hagas debido a la falta de asimilar las sutilezas.
NOTA:
La discusión sobre el
typeofoperador puede parecer una omisión evidente, pero realmente no es útil para ayudar a identificar si un tipoobjectes dado, ya que es muy simplista. Comprender dóndetypeofes útil es importante, pero actualmente no siento que sea terriblemente relevante para esta discusión. Sin embargo, mi mente está abierta al cambio. :)fuente
constructormétodo del objeto (ya sea con.toString()o.name) no funcionará si su Javascript se ha minimizado con una herramienta como uglify o la canalización de activos de Rails. La minificación cambia el nombre del constructor, por lo que terminará con nombres de clase incorrectos comon. Si se encuentra en este escenario, es posible que desee definir manualmente unaclassNamepropiedad en sus objetos y usarla en su lugar.La respuesta de Jason Bunting me dio una pista suficiente para encontrar lo que necesitaba:
Entonces, por ejemplo, en el siguiente fragmento de código:
myInstance.constructor.nameVolvería"MyObject".fuente
function getType(o) { return o && o.constructor && o.constructor.name }Un pequeño truco que uso:
fuente
class Square, el nombre esSquare.name/ enMySquare.constructor.namelugar deSquare.prototype.name; al ponernamela función de constructor no contamina el prototipo ni ninguna instancia, pero es accesible desde cualquiera de ellos.Actualizar
Para ser precisos, creo que OP solicitó una función que recupere el nombre del constructor para un objeto en particular. En términos de Javascript,
objectno tiene un tipo pero es un tipo de y en sí mismo . Sin embargo, diferentes objetos pueden tener diferentes constructores .Nota: el siguiente ejemplo está en desuso.
Una publicación de blog vinculada por Christian Sciberras contiene un buen ejemplo sobre cómo hacerlo. Es decir, al extender el prototipo de objeto:
fuente
test.getClassName()vsgetClassName.apply(test).Usando Object.prototype.toString
Resulta que, como se detalla en esta publicación, puede usar Object.prototype.toString, la implementación genérica y de bajo nivel de toString, para obtener el tipo para todos los tipos integrados
Se podría escribir una función auxiliar breve como
fuente
.slice():Object.prototype.toString.call(obj).slice( 8, -1 );Aquí hay una solución que se me ocurrió que resuelve las deficiencias de instanceof. Puede verificar los tipos de un objeto desde ventanas cruzadas y marcos cruzados y no tiene problemas con los tipos primitivos.
isInstance requiere dos parámetros: un objeto y un tipo. El verdadero truco de cómo funciona es que comprueba si el objeto proviene de la misma ventana y, si no, obtiene la ventana del objeto.
Ejemplos:
El argumento tipo también puede ser una función de devolución de llamada que devuelve un constructor. La función de devolución de llamada recibirá un parámetro que es la ventana del objeto proporcionado.
Ejemplos:
Una cosa a tener en cuenta es que IE <9 no proporciona el constructor en todos los objetos, por lo que la prueba anterior para NodeList devolvería falso y también un isInstance (alerta, "Función") devolvería falso.
fuente
En realidad estaba buscando algo similar y me encontré con esta pregunta. Así es como obtengo tipos: jsfiddle
fuente
Deberías usar
somevar.constructor.namecomo:fuente
Úselo
constructor.namecuando pueda y regex funcione cuando yo no pueda.fuente
La función kind () de Agave.JS devolverá:
Funciona en todos los objetos JS y primitivas, independientemente de cómo se crearon , y no tiene ninguna sorpresa. Ejemplos:
Números
Yaya
Instrumentos de cuerda
Booleanos
Matrices
Objetos
fechas
Las funciones
indefinido
nulo
fuente
Puede usar el
instanceofoperador para ver si un objeto es una instancia de otro, pero como no hay clases, no puede obtener un nombre de clase.fuente
instanceofsolo comprueba si un objeto hereda de otros objetos. Por ejemplo, un simple[]hereda de Array, pero Array también hereda de Object. Como la mayoría de los objetos tienen múltiples niveles de herencia, encontrar el prototipo más cercano es una mejor técnica. Vea mi respuesta de cómo.Aquí hay una implementación basada en la respuesta aceptada :
Solo usamos la propiedad constructor cuando no tenemos otra opción.
fuente
Puede usar el operador "instanceof" para determinar si un objeto es una instancia de una determinada clase o no. Si no conoce el nombre del tipo de un objeto, puede usar su propiedad de constructor. La propiedad constructora de los objetos, es una referencia a la función que se utiliza para inicializarlos. Ejemplo:
Ahora c1.constructor es una referencia a la
Circle()función. También puede usar eltypeofoperador, pero eltypeofoperador muestra información limitada. Una solución es usar eltoString()método del objeto global Object. Por ejemplo, si tiene un objeto, por ejemplo, myObject, puede usar eltoString()método del objeto global para determinar el tipo de la clase de myObject. Utilizar este:fuente
Di que tienes
var obj;Si solo desea el nombre del tipo de obj, como "Objeto", "Matriz" o "Cadena", puede usar esto:
fuente
Lo más cercano que puede obtener es
typeof, pero solo devuelve "objeto" para cualquier tipo de tipo personalizado. Para aquellos, ver Jason Bunting .Editar, Jason ha eliminado su publicación por alguna razón, así que solo usa la
constructorpropiedad de Object .fuente
Si alguien estaba buscando una solución que funciona con jQuery, aquí está el código wiki ajustado (el original rompe jQuery).
fuente
getNamey se cae.Lodash tiene muchos métodos isMe, así que si estás usando Lodash, tal vez un mixin como este pueda ser útil:
Agrega un método a lodash llamado "identificar" que funciona de la siguiente manera:
Plunker: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
fuente
Ok, amigos, he estado construyendo lentamente un método catch all para esto durante algunos años, ¡jaja! El truco es:
Para ver un ejemplo (o para ver cómo solucioné el problema), mire el siguiente código en github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js y busque:
classOf =,classOfIs =Y odefineSubClass =(sin las comillas invertidas ( `)).Como puede ver, tengo algunos mecanismos para forzarme
classOfa darme siempre el nombre del tipo de clases / constructores, independientemente de si es una clase primitiva, definida por el usuario, un valor creado usando un constructor nativo, Null, NaN, etc. Por cada valor de JavaScript obtendré su nombre de tipo único de laclassOffunción. Además, puedo pasar a constructores realessjl.classOfIspara verificar el tipo de un valor, ¡además de poder pasar su nombre de tipo también! Así por ejemplo:`` // ¡Por favor, perdona los largos espacios de nombres! No tenía idea del impacto hasta después de usarlos por un tiempo (apestan jaja)
`` `
Si está interesado en leer más sobre cómo uso la configuración mencionada anteriormente, eche un vistazo al repositorio: https://github.com/elycruz/sjljs
También libros con contenido sobre el tema: - "Patrones JavaScript" de Stoyan Stefanov. - "Javascript - La guía definitiva". por David Flanagan. - y muchos otros .. (buscar le` web).
También puede probar rápidamente las características de las que estoy hablando aquí: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (también la ruta 0.5.18 en la url tiene las fuentes de github allí menos los node_modules y tal).
¡Feliz codificación!
fuente
¡Bastante simple!
fuente
Uso
class.name. Esto también funciona confunction.name.fuente
classy no instancia.