¿Hay alguna forma 'armoniosa' de obtener el nombre de clase de la instancia de clase ES6? Otro que
someClassInstance.constructor.name
Actualmente cuento con la implementación de Traceur. Y parece que Babel tiene un polyfill Function.name
mientras que Traceur no.
Para resumir todo: no había otra forma en ES6 / ES2015 / Harmony, y no se espera nada ATM en ES.Next.
Puede proporcionar patrones útiles para aplicaciones no minificadas del lado del servidor, pero no es deseado en aplicaciones destinadas a navegador / escritorio / móvil.
Babel utiliza elcore-js
polyfill Function.name
, debe cargarse manualmente para las aplicaciones Traceur y TypeScript, según corresponda.
javascript
ecmascript-6
traceur
Frasco Estus
fuente
fuente
instance.constructor.name
yclass.name
devuelva el nombre de la clase en ES6 adecuado.someClassInstance.constructor.name
se destrozará si uglifica su código..constructor
.Respuestas:
someClassInstance.constructor.name
es exactamente la forma correcta de hacer esto. Los transpiladores pueden no admitir esto, pero es la forma estándar según la especificación. (Laname
propiedad de las funciones declaradas a través de las producciones de ClassDeclaration se establece en 14.5.15 , paso 6.)fuente
someClassInstance.constructor
es una función. Todas las funciones tienen unname
propiedad que tiene su nombre. Es por eso que Babel no necesita hacer nada. Consulte developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Como dice @Domenic, úsalo
someClassInstance.constructor.name
. @Esteban menciona en los comentarios quePor lo tanto, para acceder al nombre de la clase de forma estática, haga lo siguiente (esto funciona con mi versión de Babel, por cierto. Según los comentarios en @Domenic, su kilometraje puede variar).
Actualizar
Babel estaba bien, pero uglify / minification terminó causándome problemas. Estoy haciendo un juego y estoy creando un hash de recursos de Sprite agrupados (donde la clave es el nombre de la función). Después de la minificación, cada función / clase fue nombrada
t
. Esto mata el hash. Estoy usandoGulp
en este proyecto, y después de leer los documentos de gulp-uglify descubrí que hay un parámetro para evitar que ocurra esta alteración del nombre de la variable / función local. Entonces, en mi trago cambié.pipe($.uglify())
a.pipe($.uglify({ mangle: false }))
Aquí hay una compensación entre rendimiento y legibilidad. No alterar los nombres dará como resultado un archivo de compilación (ligeramente) más grande (más recursos de red) y una ejecución de código potencialmente más lenta (cita necesaria - puede ser BS). Por otro lado, si lo mantuviera igual, tendría que definirlo manualmente
getClassName
en cada clase de ES6, a nivel estático y de instancia. ¡No, gracias!Actualizar
Después de la discusión en los comentarios, parece que evitar la
.name
convención a favor de definir esas funciones es un buen paradigma. Solo toma unas pocas líneas de código y permitirá la minificación completa y la generalidad de su código (si se usa en una biblioteca). Así que supongo que cambio de opinión y definiré manualmentegetClassName
en mis clases. Gracias @estus! . Getter / Setters suelen ser una buena idea en comparación con el acceso variable directo de todos modos, especialmente en una aplicación basada en el cliente.fuente
reserved
opción Uglify (se puede obtener una lista de clases con regexp o lo que sea).name
patrón ordenado puede ser simplemente ganar-ganar. Lo mismo se puede aplicar a Node, pero en menor medida (por ejemplo, la aplicación de Electron ofuscado). Como regla general, confiaríaname
en el código del servidor, pero no en el código del navegador y no en la biblioteca común.name
utilicé el código DRYer para extraer el nombre de la entidad que usa la clase (servicio, complemento, etc.) del nombre de la clase, pero al final descubrí que lo duplica explícitamente con el accesorio estático (id
,_name
) Es el enfoque más sólido. Una buena alternativa es no preocuparse por el nombre de la clase, usar una clase en sí misma (objeto de función) como un identificador para una entidad que está asignada a esta clase yimport
cuando sea necesario (un enfoque que fue utilizado por Angular 2 DI).Obtener el nombre de la clase directamente de la clase
Las respuestas anteriores explicaron que
someClassInstance.constructor.name
funciona bien, pero si necesita convertir mediante programación el nombre de la clase en una cadena y no desea crear una instancia solo para eso, recuerde que:Y, dado que cada función tiene una
name
propiedad, otra buena manera de obtener una cadena con el nombre de su clase es simplemente hacer:Lo que sigue es un buen ejemplo de por qué esto es útil.
Cargando componentes web
Como nos enseña la documentación de MDN , así es como carga un componente web:
¿
YourComponent
Desde dónde se extiende una claseHTMLElement
? Dado que se considera una buena práctica nombrar la clase de su componente después de la etiqueta del componente en sí, sería bueno escribir una función auxiliar que todos sus componentes puedan usar para registrarse. Así que aquí está esa función:Entonces, todo lo que necesitas hacer es:
Lo cual es bueno porque es menos propenso a errores que escribir la etiqueta del componente usted mismo. Para concluir, esta es la
upperCamelCaseToSnakeCase()
función:fuente
Para la transpilación de babel (antes de la minificación)
Si está utilizando Babel con
@babel/preset-env
, es posible mantener las definiciones de clases sin convertirlas en funciones (lo que elimina elconstructor
propiedad)Puede eliminar cierta compatibilidad del navegador anterior con esta configuración en su
babel.config / babelrc
:Para la minificación de babel (después de la transpilación)
Parece que no hay una solución fácil en este momento ... Necesitamos analizar las exclusiones.
fuente
class Foo {}
se reducirá a algo parecidoclass a{}
a cualquier objetivo. No habráFoo
palabra en el código fuente minificado.export class Foo{}
no se pueden uglificar más eficientemente, pero esto puede ser diferente en otros lugares, no podemos saber exactamente sin tener una buena idea de lo que sucede con piezas de código específicas en el momento de la compilación. De cualquier manera, esto no ha cambiado desde 2015. Siempre fue posible para algunas configuraciones y código de compilación. Y diría que esta posibilidad aún es demasiado frágil para usar nombres de clase para la lógica de la aplicación. El nombre de la clase en la que confía puede convertirse en basura después de un cambio accidental en el código fuenteconstructor.name
en la versión minimizada ... ilógico: /