Existem maneiras 'harmoniosas' de obter o nome da classe da instância da classe ES6? Outro que não seja
someClassInstance.constructor.name
Atualmente, estou contando com a implementação do Traceur. E parece que Babel tem um polyfill por Function.name
enquanto Traceur não.
Para resumir tudo: não havia outro caminho no ES6 / ES2015 / Harmony, e nada é esperado no caixa eletrônico no ES.Next.
Ele pode fornecer padrões úteis para aplicativos do servidor não minificados, mas é indesejável em aplicativos destinados ao navegador / desktop / celular.
Babel usacore-js
para polyfill Function.name
; ele deve ser carregado manualmente para aplicativos Traceur e TypeScript conforme apropriado.
javascript
ecmascript-6
traceur
Estus Flask
fonte
fonte
instance.constructor.name
eclass.name
retorne o nome da classe no ES6 adequado.someClassInstance.constructor.name
será confundido se você atualizar seu código..constructor
.Respostas:
someClassInstance.constructor.name
é exatamente a maneira correta de fazer isso. Os transpilers podem não suportar isso, mas é o caminho padrão conforme a especificação. (Aname
propriedade das funções declaradas por meio das produções ClassDeclaration é definida em 14.5.15 , etapa 6.)fonte
someClassInstance.constructor
é uma função. Todas as funções têm umaname
propriedade definida como seu nome. É por isso que babel não precisa fazer nada. Por favor, veja developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…Como o @Domenic diz, use
someClassInstance.constructor.name
. @Esteban menciona nos comentários quePortanto, para acessar o nome da classe estaticamente, faça o seguinte (isso funciona com minha versão Babel BTW. De acordo com os comentários em @Domenic, sua milhagem pode variar).
Atualizar
Babel estava bem, mas uglify / minification acabou me causando problemas. Estou criando um jogo e criando um hash de recursos de Sprite em pool (onde a chave é o nome da função). Após a minificação, todas as funções / classes foram nomeadas
t
. Isso mata o hash. Estou usandoGulp
neste projeto e, depois de ler os documentos do gulp-uglify , descobri que há um parâmetro para impedir que essa variável / nome da função local seja alterada . Então, no meu gulpfile eu mudei.pipe($.uglify())
para.pipe($.uglify({ mangle: false }))
Há uma troca de desempenho versus legibilidade aqui. Não manipular os nomes resultará em um arquivo de compilação (um pouco) maior (mais recursos de rede) e execução de código potencialmente mais lenta (citação necessária - pode ser BS). Por outro lado, se eu mantivesse o mesmo, teria que definir manualmente
getClassName
em todas as classes ES6 - no nível estático e de instância. Não, obrigado!Atualizar
Após a discussão nos comentários, parece que evitar a
.name
convenção em favor da definição dessas funções é um bom paradigma. Leva apenas algumas linhas de código e permitirá minificação e generalidade completas do seu código (se usado em uma biblioteca). Acho que mudo de idéia e defino manualmentegetClassName
nas minhas aulas. Obrigado @estus! . Getter / Setters geralmente são uma boa idéia em comparação com o acesso direto a variáveis de qualquer maneira, especialmente em um aplicativo baseado em cliente.fonte
reserved
manipulação com a opção Uglify (uma lista de classes pode ser obtida com regexp ou o que for).name
padrão puro pode ser apenas uma vantagem para todos. O mesmo pode ser aplicado ao Nó, mas em menor grau (por exemplo, aplicativo Electron ofuscado). Como regra geral, eu confiaria noname
código do servidor, mas não no código do navegador e na biblioteca comum.name
código DRYer para extrair o nome da entidade que usa a classe (serviço, plug-in, etc.) do nome da classe, mas no final, descobri que a duplicava explicitamente com prop estático (id
,_name
) é apenas a abordagem mais sólida. Uma boa alternativa é não se importar com o nome da classe, usar a própria classe (objeto de função) como um identificador para uma entidade que é mapeada para essa classe eimport
sempre que necessário (uma abordagem usada pelo Angular 2 DI).Obtendo o nome da turma diretamente da turma
As respostas anteriores explicaram que
someClassInstance.constructor.name
funciona muito bem, mas se você precisar converter programaticamente o nome da classe em uma string e não desejar criar uma instância apenas para isso, lembre-se:E, como toda função tem uma
name
propriedade, outra maneira agradável de obter uma string com o nome da sua classe é:O que se segue é um bom exemplo de por que isso é útil.
Carregando componentes da Web
Como a documentação do MDN nos ensina, é assim que você carrega um componente da web:
Onde
YourComponent
uma classe se estendeHTMLElement
. Como é uma boa prática nomear a classe do seu componente após a própria tag do componente, seria bom escrever uma função auxiliar que todos os seus componentes pudessem usar para se registrar. Então aqui está essa função:Então, tudo que você precisa fazer é:
O que é legal porque é menos propenso a erros do que você mesmo escrever a tag do componente. Para finalizar, esta é a
upperCamelCaseToSnakeCase()
função:fonte
Para transpilação de babel (antes da minificação)
Se você estiver usando o Babel
@babel/preset-env
, é possível manter as definições de classes sem convertê-las em funções (o que remove aconstructor
propriedade)Você pode descartar alguma compatibilidade antiga do navegador com esta configuração em
babel.config / babelrc
:Para minificação de babel (após transpilação)
Parece que não há uma solução fácil no momento ... Precisamos examinar exclusões desconcertantes.
fonte
class Foo {}
será reduzido para algo comoclass a{}
com qualquer alvo. Não haveráFoo
palavra no código fonte minificado.export class Foo{}
não podem ser melhorados com eficiência, mas isso pode ser diferente em outros lugares; não podemos saber exatamente exatamente sem ter uma boa idéia do que acontece com partes de código específicas no momento da construção. De qualquer forma, isso não mudou desde 2015. Sempre foi possível para algumas configurações e códigos de compilação. E eu diria que essa possibilidade ainda é muito frágil para usar nomes de classe para a lógica do aplicativo. O nome da classe em que você confia pode se tornar lixo após uma alteração acidental no código-fonteconstructor.name
ainda funciona na versão minificada ... ilógico: /