w3schools variable node es6 clases attribute javascript ecmascript-6 traceur

variable - javascript class w3schools



Obtenga el nombre de clase de la instancia de clase ES6 (3)

¿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 para Function.name mientras que Traceur no.

Para resumirlo 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 usa core-js para rellenar poly.Function.name, debe cargarse manualmente para aplicaciones Traceur y TypeScript, según corresponda.


Obtener el nombre de la clase directamente de la clase

Las respuestas anteriores explicaron que someClassInstance.constructor.name funciona bien, pero si necesita convertir programáticamente el nombre de la clase en una cadena y no desea crear una instancia solo para eso, recuerde que:

typeof YourClass === "function"

Y, dado que cada función tiene una propiedad de name , otra buena manera de obtener una cadena con el nombre de su clase es simplemente hacer:

YourClass.name

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:

customElements.define("your-component", YourComponent);

Donde YourComponent es una clase que se extiende desde HTMLElement . Como 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:

function registerComponent(componentClass) { const componentName = upperCamelCaseToSnakeCase(componentClass.name); customElements.define(componentName, componentClass); }

Entonces, todo lo que necesitas hacer es:

registerComponent(YourComponent);

Lo cual es bueno porque es menos propenso a errores que escribir la etiqueta del componente usted mismo. Para concluir, esta es la función upperCamelCaseToSnakeCase() :

// converts `YourString` into `your-string` function upperCamelCaseToSnakeCase(value) { return value // first char to lower case .replace(/^([A-Z])/, $1 => $1.toLowerCase()) // following upper chars get preceded with a dash .replace(/([A-Z])/g, $1 => "-" + $1.toLowerCase()); }


Como dice @Domenic, use someClassInstance.constructor.name . @Esteban menciona en los comentarios que

someClassInstance.constructor es una función. Todas las funciones tienen una propiedad de name ...

Por 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).

class SomeClass { constructor() {} } var someClassInstance = new SomeClass(); someClassInstance.constructor.name; // === ''SomeClass'' SomeClass.name // === ''SomeClass''

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 se denominó t . Esto mata el hash. Estoy usando Gulp 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 (se necesita una cita, puede ser BS). Por otro lado, si lo mantuve igual, tendría que definir 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 convención .name en 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 getClassName manualmente getClassName 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.

class SomeClass { constructor() {} static getClassName(){ return ''SomeClass''; } getClassName(){ return SomeClass.getClassName(); } } var someClassInstance = new SomeClass(); someClassInstance.constructor.getClassName(); // === ''SomeClass'' (static fn) someClassInstance.getClassName(); // === ''SomeClass'' (instance fn) SomeClass.getClassName() // === ''SomeClass'' (static fn)


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. (La propiedad de name de las funciones declaradas a través de las producciones de ClassDeclaration se establece en 14.5.15 , paso 6.)