Existe uma JavaScript equivalente de Java s' class.getName()
?
javascript
Ewen Cartwright
fonte
fonte
Respostas:
Não .
Atualização do ES2015 : o nome de
class Foo {}
éFoo.name
. O nome dathing
classe de, independentemente dothing
tipo, éthing.constructor.name
. Construtores internos em um ambiente ES2015 têm aname
propriedade correta ; por exemplo(2).constructor.name
é"Number"
.Mas aqui estão vários hacks que caem de uma maneira ou de outra:
Aqui está um truque que fará o que você precisa - saiba que ele modifica o protótipo do objeto, algo que as pessoas desaprovam (geralmente por um bom motivo)
Agora, todos os seus objetos terão a função,,
getName()
que retornará o nome do construtor como uma string. Eu testei issoFF3
eIE7
não posso falar em outras implementações.Se você não quiser fazer isso, aqui está uma discussão sobre as várias maneiras de determinar tipos em JavaScript ...
Eu atualizei isso recentemente para ser um pouco mais exaustivo, embora dificilmente seja isso. Correções bem-vindas ...
Usando a
constructor
propriedade ...Cada
object
um tem um valor para suaconstructor
propriedade, mas, dependendo de como issoobject
foi construído e do que você deseja fazer com esse valor, ele pode ou não ser útil.De um modo geral, você pode usar a
constructor
propriedade para testar o tipo de objeto da seguinte maneira:Então, isso funciona bem o suficiente para a maioria das necessidades. Dito isto...
Ressalvas
Não vai funcionar AT ALL , em muitos casos
Esse padrão, embora quebrado, é bastante comum:
Objects
construído vianew Thingy
terá umaconstructor
propriedade que aponta paraObject
, nãoThingy
. Então, caímos logo no início; você simplesmente não pode confiarconstructor
em uma base de código que não controla.Herança múltipla
Um exemplo em que não é tão óbvio é usar herança múltipla:
As coisas agora não funcionam como você pode esperar:
Portanto, você poderá obter resultados inesperados se o
object
teste tiver umobject
conjunto diferenteprototype
. Existem maneiras de contornar isso fora do escopo desta discussão.Existem outros usos para a
constructor
propriedade, alguns interessantes, outros nem tanto; por enquanto não nos aprofundaremos nesses usos, pois não é relevante para esta discussão.Não funcionará em quadros cruzados e em janelas cruzadas
O uso
.constructor
da verificação de tipo será interrompido quando você quiser verificar o tipo de objetos provenientes de diferenteswindow
objetos, digamos o de um iframe ou uma janela pop-up. Isso ocorre porque há uma versão diferente de cada tipo de núcleoconstructor
em cada `janela ', ou seja,Usando o
instanceof
operador ...O
instanceof
operador também é uma maneira limpa de testarobject
, mas tem seus próprios problemas em potencial, assim como aconstructor
propriedade.Mas
instanceof
falha ao trabalhar com valores literais (porque literais não sãoObjects
)Os literais precisam ser agrupados em um
Object
parainstanceof
que funcionem, por exemploA
.constructor
verificação funciona bem para literais, porque a.
invocação do método envolve implicitamente os literais em seu respectivo tipo de objetoPor que dois pontos para os 3? Porque o Javascript interpreta o primeiro ponto como um ponto decimal;)
Não funcionará em quadros cruzados e em janelas cruzadas
instanceof
também não funcionará em janelas diferentes, pelo mesmo motivo que aconstructor
verificação de propriedade.Usando a
name
propriedade daconstructor
propriedade ...Não funciona AT ALL , em muitos casos
Mais uma vez, veja acima; é bastante comum
constructor
estar completamente e completamente errado e inútil.NÃO funciona no <IE9
O uso
myObjectInstance.constructor.name
fornecerá uma string contendo o nome daconstructor
função usada, mas está sujeita às advertências sobre aconstructor
propriedade mencionada anteriormente.Para o IE9 e superior, você pode fazer um patch de macaco no suporte :
Versão atualizada do artigo em questão. Isso foi adicionado três meses após a publicação do artigo. Essa é a versão recomendada para uso pelo autor do artigo, Matthew Scharley. Essa mudança foi inspirada em comentários apontando possíveis armadilhas no código anterior.
Usando Object.prototype.toString
Acontece que, como este post detalha , você pode usar
Object.prototype.toString
- o baixo nível e implementação genérica detoString
- para obter o tipo para todos os tipos internosPode-se escrever uma função auxiliar curta, como
para remover a crosta e obter apenas o nome do tipo
No entanto, ele retornará
Object
para todos os tipos definidos pelo usuário.Advertências para todos ...
Tudo isso está sujeito a um problema em potencial, e essa é a questão de como o objeto em questão foi construído. Aqui estão várias maneiras de criar objetos e os valores que os diferentes métodos de verificação de tipo retornarão:
Embora nem todas as permutações estejam presentes neste conjunto de exemplos, espero que haja o suficiente para fornecer uma idéia sobre como as coisas podem ficar confusas dependendo de suas necessidades. Não assuma nada, se você não entender exatamente o que está procurando, poderá acabar com a quebra de código onde não espera, devido à falta de grokking nas sutilezas.
NOTA:
A discussão sobre o
typeof
operador pode parecer uma omissão flagrante, mas realmente não é útil para ajudar a identificar se umobject
é um determinado tipo, pois é muito simplista. Entender ondetypeof
é útil é importante, mas atualmente não acho que seja terrivelmente relevante para essa discussão. Minha mente está aberta para mudar. :)fonte
constructor
método do objeto (com.toString()
ou.name
) não funcionará se o seu Javascript tiver sido minificado com uma ferramenta como uglify ou o pipeline de ativos do Rails. A minificação renomeia o construtor, assim você terminará com nomes de classe incorretos comon
. Se você estiver nesse cenário, defina manualmente manualmente umaclassName
propriedade em seus objetos e use-a.A resposta de Jason Bunting me deu uma pista suficiente para encontrar o que eu precisava:
Então, por exemplo, no seguinte trecho de código:
myInstance.constructor.name
voltaria"MyObject"
.fonte
function getType(o) { return o && o.constructor && o.constructor.name }
Um pequeno truque que eu uso:
fonte
class Square
, o nome éSquare.name
/ emMySquare.constructor.name
vez deSquare.prototype.name
; colocandoname
a função construtora, ela não polui o protótipo ou qualquer instância, mas é acessível a partir de qualquer uma.Atualizar
Para ser mais preciso, acho que o OP solicitou uma função que recupera o nome do construtor para um objeto específico. Em termos de Javascript,
object
não tem um tipo, mas é um tipo de e por si só . No entanto, objetos diferentes podem ter construtores diferentes .Nota: o exemplo abaixo está obsoleto.
Um post no blog de Christian Sciberras contém um bom exemplo de como fazê-lo. Ou seja, estendendo o protótipo de objeto:
fonte
test.getClassName()
vsgetClassName.apply(test)
.Usando Object.prototype.toString
Acontece que, como esta postagem detalha, você pode usar Object.prototype.toString - a implementação genérica e de baixo nível do toString - para obter o tipo para todos os tipos internos
Pode-se escrever uma função auxiliar curta, como
fonte
.slice()
:Object.prototype.toString.call(obj).slice( 8, -1 );
Aqui está uma solução que eu inventei que resolve as deficiências de instanceof. Ele pode verificar os tipos de um objeto nas janelas e quadros cruzados e não tem problemas com os tipos primitivos.
isInstance requer dois parâmetros: um objeto e um tipo. O verdadeiro truque de como funciona é que ele verifica se o objeto é da mesma janela e se não obtém a janela do objeto.
Exemplos:
O argumento type também pode ser uma função de retorno de chamada que retorna um construtor. A função de retorno de chamada receberá um parâmetro que é a janela do objeto fornecido.
Exemplos:
Um aspecto a ter em mente é que o IE <9 não fornece o construtor em todos os objetos, portanto o teste acima para NodeList retornaria false e também um isInstance (alert, "Function") retornaria false.
fonte
Na verdade, eu estava procurando uma coisa semelhante e me deparei com essa pergunta. Aqui está como eu obtenho tipos: jsfiddle
fonte
Você deve usar
somevar.constructor.name
como:fonte
Use
constructor.name
quando puder e regex funcione quando não puder.fonte
A função kind () do Agave.JS retornará:
Ele funciona em todos os objetos JS e primitivos, independentemente de como eles foram criados , e não tem nenhuma surpresa. Exemplos:
Números
NaN
Cordas
Booleanos
Matrizes
Objetos
datas
Funções
Indefinido
nulo
fonte
Você pode usar o
instanceof
operador para verificar se um objeto é uma instância de outro, mas como não há classes, não é possível obter um nome de classe.fonte
instanceof
apenas verifica se um objeto herda de outros objetos. Por exemplo, um simples[]
herda de Array, mas Array também herda de Object. Como a maioria dos objetos tem vários níveis de herança, encontrar o protótipo mais próximo é uma técnica melhor. Veja minha resposta para saber como.Aqui está uma implementação baseada na resposta aceita :
Só usamos a propriedade construtora quando não temos outra opção.
fonte
Você pode usar o operador "instanceof" para determinar se um objeto é uma instância de uma determinada classe ou não. Se você não souber o nome do tipo de um objeto, poderá usar sua propriedade construtora. A propriedade construtora de objetos é uma referência à função usada para inicializá-los. Exemplo:
Agora c1.constructor é uma referência à
Circle()
função. Você também pode usar otypeof
operador, mas otypeof
operador mostra informações limitadas. Uma solução é usar otoString()
método do objeto global Object. Por exemplo, se você tiver um objeto, digamos myObject, poderá usar otoString()
método do Global Object para determinar o tipo da classe de myObject. Usa isto:fonte
Diga que você tem
var obj;
Se você deseja apenas o nome do tipo de obj, como "Objeto", "Matriz" ou "Cadeia de caracteres", use:
fonte
O mais próximo que você pode chegar é
typeof
, mas ele retorna apenas "objeto" para qualquer tipo de tipo personalizado. Para aqueles, veja Jason Bunting .Editar, Jason excluiu sua postagem por algum motivo, então use a
constructor
propriedade de Object .fonte
Se alguém estava procurando uma solução que esteja trabalhando com jQuery, aqui está o código wiki ajustado (o original quebra o jQuery).
fonte
getName
e cai.O Lodash possui muitos isMethods, portanto, se você estiver usando o Lodash, talvez um mixin como este possa ser útil:
Ele adiciona um método ao lodash chamado "identificar", que funciona da seguinte maneira:
Plunker: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
fonte
Ok, pessoal, eu venho desenvolvendo lentamente todo esse método há alguns anos, lol! O truque é:
Para um exemplo (ou para ver como eu lidei com o problema), consulte o seguinte código no github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js e procure por:
classOf =
,classOfIs =
, E oudefineSubClass =
(sem os crases ( `)).Como você pode ver, eu tenho alguns mecanismos para forçar
classOf
a sempre me fornecer o nome do tipo classes / construtores, independentemente de ser uma classe primitiva, definida pelo usuário, um valor criado usando um construtor nativo, Nulo, NaN, etc. Para cada valor javascript, recebo seu nome de tipo exclusivo daclassOf
função. Além disso, posso passar os construtores reaissjl.classOfIs
para verificar o tipo de um valor, além de poder passar também o nome do tipo! Então, por exemplo:`` // Por favor, perdoe longos espaços para nome! Eu não tinha idéia do impacto até depois de usá-los por um tempo (eles sugam haha)
`` ``
Se você estiver interessado em ler mais sobre como eu uso a configuração mencionada acima, consulte o repositório: https://github.com/elycruz/sjljs
Também livros com conteúdo sobre o assunto: - "JavaScript Patterns", de Stoyan Stefanov. - "Javascript - O Guia Definitivo". de David Flanagan. - e muitos outros .. (pesquise le` web).
Além disso, você pode testar rapidamente os recursos de que estou falando aqui: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (também o caminho 0.5.18 no URL contém as fontes do github lá menos o node_modules e tal).
Feliz codificação!
fonte
Relativamente simples!
fonte
Use
class.name
. Isso também funciona comfunction.name
.fonte
class
e não instância.