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