Como você verifica se um valor é um objeto em JavaScript?
javascript
object
types
javascript-objects
Danny Fox
fonte
fonte
null
é um objeto).Respostas:
ATUALIZAÇÃO :
Essa resposta está incompleta e fornece resultados enganosos . Por exemplo,
null
também é considerado do tipoobject
JavaScript, sem mencionar vários outros casos extremos. Siga a recomendação abaixo e passe para a outra "resposta mais votada (e correta!)" .Resposta original :
Tente usar
typeof(var)
e / ouvar instanceof something
.EDIT: Essa resposta dá uma idéia de como examinar as propriedades de variáveis, mas é não uma receita à prova de balas (afinal de contas não há nenhuma receita em tudo!) Para verificar se ele é um objeto, longe disso. Como as pessoas tendem a procurar algo para copiar daqui sem fazer nenhuma pesquisa, eu recomendo que elas se voltem para a outra resposta mais votada (e correta!).
fonte
typeof
é um operador, então não há necessidade()
.typeof
retorna 'objeto' para nulo, que não é um objeto, einstanceof
não funciona para objetos criados usandoObject.create(null)
.Se
typeof yourVariable === 'object'
, é um objeto ou nulo. Se você deseja excluir nulo, apenas faça-otypeof yourVariable === 'object' && yourVariable !== null
.fonte
yourVariable !== null
uma prática melhor?typeof null == 'object'
não será corrigido no ES6 . Eles disseram:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
typeof
porque há alguns casos especiais que não fazem necessariamente muito sentido. Se você está tentando diferenciar matrizes e objetos que não são matrizes, definitivamente não deseja usartypeof
.Object.prototype.toString.call(yourVar)
, sendo sua Var o que você precisa inspecionar. Em caso de matrizes,Object.prototype.toString.call([1,2])
retornos[object Array]
Vamos definir "objeto" em Javascript . De acordo com os documentos MDN , todo valor é um objeto ou um primitivo:
O que é um primitivo?
3
'abc'
true
null
undefined
O que é um objeto (ou seja, não é um primitivo)?
Object.prototype
Object.prototype
Function.prototype
Object
Function
function C(){}
- funções definidas pelo usuárioC.prototype
- a propriedade prototype de uma função definida pelo usuário: este nãoC
é um protótiponew C()
- "novo" - em uma função definida pelo usuárioMath
Array.prototype
{"a": 1, "b": 2}
- objetos criados usando notação literalnew Number(3)
- invólucros em torno de primitivosObject.create(null)
Object.create(null)
Como verificar se um valor é um objeto
instanceof
por si só não funcionará, porque perde dois casos:typeof x === 'object'
não funcionará, devido a falsos positivos (null
) e falsos negativos (funções):Object.prototype.toString.call
não funcionará, por causa de falsos positivos para todas as primitivas:Então eu uso:
A resposta de @ Daan também parece funcionar:
porque, de acordo com os documentos MDN :
Uma terceira maneira que parece funcionar (não tenho certeza se é 100%) é usar o
Object.getPrototypeOf
que gera uma exceção se o argumento não for um objeto:fonte
obj === Object(obj)
retornatrue
para matrizes.var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
não funciona, por exemplo, com proxies revogados, que são objetos, mas jogam.({}).toString.apply(obj) === '[object Object]'
Isto distingue entre matrizes e objetos que não são matrizesO underscore.js fornece o seguinte método para descobrir se algo é realmente um objeto:
ATUALIZAR
Devido a um erro anterior na V8 e à otimização menor da micro velocidade, o método é o seguinte desde underscore.js 1.7.0 (agosto de 2014):
fonte
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
também. Deve ser a resposta aceita.Object.prototype.toString.call(myVar)
retornará:"[object Object]"
se myVar é um objeto"[object Array]"
se myVar for uma matrizPara obter mais informações sobre isso e por que é uma boa alternativa ao typeof, confira este artigo .
fonte
typeof [] === 'object'
->true
. É disso que você precisa desse método.Object.prototype.toString.call(3)
->"[object Number]"
.Object.prototype.toString.call(new Number(3))
->"[object Number]
"getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Para simplesmente verificar contra Objeto ou Matriz sem chamada de função adicional (velocidade). Como também postado aqui .
isArray ()
isObject () - Observação: use apenas para literais de objeto, pois retorna falso para objetos personalizados, como nova data ou novo YourCustomObject.
fonte
isObject
só funciona com literais de objeto. Se eu criar um tipo personalizado, crie uma instância do tipo e testá-lo, ele retornafalse
Boolean(a)
é mais longo, mas muito mais intuitivo. Só não usenew Boolean(a)
: ( aqui está o porquê )!{
caractere. Para o caso da matriz, desde que você não precise oferecer suporte ao IE <9, você pode usarArray.isArray()
para determinar se algo é uma matriz. Ele passa em todos os casos de teste que você forneceu.Gosto simplesmente:
Se o item for um objeto JS, e não for um array JS, e não
null
for ... se todos os três forem verdadeiros, retornetrue
. Se alguma das três condições falhar, o&&
teste entrará em curto-circuito efalse
será devolvido. Onull
teste pode ser omitido, se desejado (dependendo de como você usanull
).DOCS:
http://devdocs.io/javascript/operators/typeof
http://devdocs.io/javascript/global_objects/object
http://devdocs.io/javascript/global_objects/array/isarray
http://devdocs.io/javascript/global_objects/null
fonte
new Date()
retorna um objeto. Uma matriz é, do ponto de vista lógico, não um objeto - embora o JavaScript manipule e relate-os como tal. Na prática, no entanto, não é útil vê-los iguais, porque não são. Um objeto não temlength
atributo, por exemplo, e não possui métodos como push (). E, às vezes, você pode querer fornecer parâmetros de sobrecarga de função, onde é necessário fazer a diferença entre uma matriz ou um objeto, especialmente se outros parâmetros dependem de qual deles foi fornecido.length
propriedade nem métodos como essepush
,Object.create(Array.prototype)
é um contra-exemplo trivial de um objeto sem matriz que os possui. O que torna as matrizes especiais é que elas são objetos exóticos com um método interno essencial personalizado, mas ainda são objetos.length
propriedade (eu quis dizer que literais de objetos não têmlength
atributo por padrão). Eu escrevi que matrizes não são objetos do ponto de vista lógico . Eu estou falando sobre lógica do programa. Às vezes é necessário verificar se uma matriz é uma matriz "real" e definitivamente não é um objeto "real". É para isso queArray.isArray()
serve. Imagine que você tem uma função que aceita um objeto ou uma matriz de objetos. Verificar um atributo ou método especial é uma solução suja. A maneira nativa é sempre melhor.typeof null
é"object"
não"undefined"
.Com função
Array.isArray
:Sem função
Array.isArray
:Apenas surpreendi quantas votações positivas por respostas erradas 😮
Apenas 1 resposta passou nos meus testes !!! Aqui eu criei minha versão simplificada:
Quanto a mim, é claro e simples, e simplesmente funciona! Aqui estão meus testes:
MAIS UMA VEZ: nem todas as respostas passam nesses testes !!! 🙈
Caso você precise verificar se o objeto é uma instância de determinada classe , verifique o construtor com sua classe específica, como:
teste simples:
Como resultado, você terá um código rigoroso e robusto!
No caso de você não vai criar funções como
isDate
,isError
,isRegExp
, etc você pode considerar a opção de usar estas funções generalizadas:não funcionará corretamente para todos os casos de teste mencionados anteriormente, mas é bom o suficiente para todos os objetos (simples ou construídos).
isObject
não funcionará no caso deObject.create(null)
por causa da implementação interna daObject.create
qual é explicada aqui, mas você pode usarisObject
em uma implementação mais sofisticada:Já existe um pacote criado no npm v1 com base nesta implementação! E funciona para todos os casos de teste descritos anteriormente! 🙂
fonte
isDate
yourDateObject com o objetivo de escrever um código robusto, caso contrário, você terá umisObject
método quebradiço .Date
no meu comentário foi mal escolhido porque sim, a resposta discuteDate
. MasDate
é apenas uma das infinitas classes possíveis e o ponto vale para qualquer outra classe. Exemplo:class Foo() { }; var x = new Foo(); isObject(x)
retornafalse
. Não sei exatamente qual é o caso de uso do OP, mas é fácil conceber cenários nos quais será inviável ter que conhecer todas as classes possíveis e verificar especificamente se cada uma delas .Oh meu Deus! Eu acho que isso poderia ser mais curto do que nunca, vamos ver o seguinte:
Código curto e final
Explicado
Tipos de retorno
tipo de objetos JavaScript (incluindo
null
) retorna"object"
Verificando seus construtores
A verificação de suas
constructor
propriedades retorna a função com seus nomes.Apresentando Function.name
Function.name
retorna um nome somente leitura de uma função ou"anonymous"
para fechamentos.fonte
Object.create(null)
e por que você faria isso de qualquer maneira ...?OK, vamos dar-lhe esse conceito antes de responder sua pergunta, em funções JavaScript são objetos, também nulo, Object, matrizes e até Data, de modo que você vê lá é não uma forma simples como typeof obj === 'objeto', então tudo o que foi mencionado acima retornará verdadeiro , mas há maneiras de verificar isso ao escrever uma função ou usar estruturas JavaScript, OK:
Agora, imagine que você tenha esse objeto que é um objeto real (não nulo, função ou matriz):
JavaScript puro:
ou
ou
ou
Você pode simplesmente usar uma dessas funções como acima em seu código chamando-as e ela retornará true se for um objeto:
Se você estiver usando uma estrutura JavaScript, eles geralmente preparam esse tipo de função para você, estas são algumas delas:
jQuery:
Angular:
Sublinhado e Lodash:
fonte
Depende do que você quer dizer com "é um objeto". Se você deseja tudo o que não é primitivo , ou seja, coisas nas quais você pode definir novas propriedades, isso deve fazer o truque:
Que exclui os primitivos (números simples /
NaN
/Infinity
, cordas simples, símbolos,true
/false
,undefined
enull
), mas deve retornar verdadeiro para tudo o resto (incluindoNumber
,Boolean
eString
objetos). Observe que o JS não define com quais objetos "host", comowindow
ouconsole
, devem retornar quando usadostypeof
, portanto, é difícil cobrir esses itens com uma verificação como esta.Se você quiser saber se algo é um objeto "simples", ou seja, foi criado como um literal
{}
ou comObject.create(null)
, você pode fazer o seguinte:Editar 2018 : como
Symbol.toStringTag
agora permite personalizar a saída deObject.prototype.toString.call(...)
, aisPlainObject
função acima pode retornarfalse
em alguns casos, mesmo quando o objeto iniciou sua vida como um literal. Indiscutivelmente, por convenção, um objeto com uma tag de string personalizada não é mais exatamente um objeto simples, mas isso atrapalha ainda mais a definição do que é um objeto simples em Javascript.fonte
instanceof Object
, dois literais de função idênticos não são estritamente iguais, são passados por referência, etc.Meu Deus, muita confusão em outras respostas.
Resposta curta
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
Para testar isso, execute as seguintes instruções no console do chrome.
Caso 1.
Caso 2.
Caso 3.
Explicação
Ok. Vamos dividir
typeof anyVar == 'object'
é retornado verdadeiro de três candidatos -[], {} and null
,anyVar instanceof Object
reduz esses candidatos a dois -[], {}
!(anyVar instanceof Array)
reduz a apenas um -{}
Rolos de tambor, por favor!
Por isso, você já deve ter aprendido a verificar a matriz em Javascript.
fonte
false
(conforme desejado) quandoanyVar
é uma função.A maneira mais razoável de verificar o tipo de um valor parece ser o
typeof
operador. O único problema é que está terrivelmente quebrado:"object"
paranull
, que pertence ao tipo Nulo."function"
para objetos que podem ser chamados, que pertencem ao tipo de objeto."unknown"
. Os únicos resultados proibidos são"function"
e tipos primitivos.typeof
é confiável apenas para nãonull
primitivos. Portanto, uma maneira de verificar se um valor é um objeto seria garantir que a sequência retornada portypeof
não corresponda a uma primitiva e que o objeto não sejanull
. No entanto, o problema é que um padrão futuro pode introduzir um novo tipo primitivo, e nosso código consideraria um objeto. Novos tipos não aparecem com frequência, mas, por exemplo, o ECMAScript 6 introduziu o tipo de símbolo.Portanto, em vez de
typeof
, apenas recomendo abordagens cujo resultado varia dependendo se o valor é um objeto ou não. O seguinte pretende ser umLista abrangente, mas não exaustiva, de maneiras adequadas de testar se um valor pertence ao tipo de Objeto.
Object
construtorO
Object
construtor coage o argumento passado para um objeto. Se já é um objeto, o mesmo objeto é retornado.Portanto, você pode usá-lo para coagir o valor a um objeto e comparar estritamente esse objeto com o valor original.
A seguinte função requer o ECMAScript 3, que foi introduzido
===
:Eu gosto dessa abordagem porque é simples e auto-descritiva, e uma verificação análoga também funcionará para booleanos, números e seqüências de caracteres. No entanto, esteja ciente de que depende do global
Object
não ser sombreado nem alterado.Construtores
Quando você instancia um construtor, ele pode retornar um valor diferente da instância recém-criada. Mas esse valor será ignorado, a menos que seja um objeto.
A função a seguir requer o ECMAScript 3, que permitiu que os construtores retornassem objetos não. Antes do ECMAScript 3, gerava um erro, mas as
try
instruções não existiam na época.Embora um pouco menos simples que o exemplo anterior, este não depende de nenhuma propriedade global e, portanto, pode ser o mais seguro.
this
valorAs especificações antigas do ECMAScript exigiam que o
this
valor fosse um objeto. Introduzido o ECMAScript 3Function.prototype.call
, que permitiu chamar uma função com umthis
valor arbitrário , mas coagido a um objeto.O ECMAScript 5 introduziu um modo estrito que removeu esse comportamento, mas no modo desleixado ainda podemos (mas provavelmente não devemos) confiar nele.
[[Protótipo]]
Todos os objetos comuns têm um slot interno chamado [[Prototype]], cujo valor determina de qual outro objeto é herdado. O valor pode ser apenas um objeto ou
null
. Portanto, você pode tentar criar um objeto que herda do valor desejado e verificar se funcionou.Ambos
Object.create
eObject.getPrototypeOf
requerem ECMAScript 5.Algumas novas maneiras do ECMAScript 6
O ECMAScript 6 apresenta algumas novas maneiras indiretas de verificar se um valor é um objeto. Eles usam a abordagem vista anteriormente para passar o valor para algum código que requer um objeto, envolvido dentro de uma
try
instrução para detectar erros. Alguns exemplos ocultos, não vale a pena comentarMostrar snippet de código
Mostrar snippet de código
Nota: ignorei intencionalmente algumas abordagens como
Object.getPrototypeOf(value)
(ES5) eReflect
métodos (ES6) porque elas chamam métodos internos essenciais que podem fazer coisas desagradáveis, por exemplo, sevalue
for um proxy. Por razões de segurança, meus exemplos fazem referência apenasvalue
sem acessá-lo diretamente.fonte
Tente isto
fonte
Object.prototype instanceof Object
-> false.Object.create(null) instanceof Object
-> falso.new Date() instanceof Object
=> truePronto para usar funções para verificação
Explicação
Em Javascript,
null
,Object
,Array
,Date
efunction
s são todos os objetos. Embora,null
seja um pouco artificial. Portanto, é melhor verificar onull
primeiro, para detectar que não é nulo.Verificando
typeof o === 'object'
garantias queo
são um objeto. Sem essa verificação, nãoObject.prototype.toString
teria sentido, pois retornaria objeto para tudo, mesmo paraundefined
enull
! Por exemplo:toString(undefined)
retorna[object Undefined]
!Após a
typeof o === 'object'
verificação, toString.call (O) é um excelente método para verificar seo
um objecto, um objecto derivado comoArray
,Date
ou umfunction
.Na
isDerivedObject
função, verifica se ao
é uma função. Porque, função também um objeto, é por isso que está lá. Se não fez isso, a função retornará como falsa. Exemplo:isDerivedObject(function() {})
retornariafalse
, porém agora retornatrue
.Sempre se pode mudar a definição do que é um objeto. Assim, pode-se alterar essas funções adequadamente.
Testes
fonte
Se você gostaria de verificar se o
prototype
for for é oobject
únicoObject
. FiltraString
,Number
,Array
,Arguments
, etc.Ou como uma função de seta de expressão única (ES6 +)
fonte
return Object.prototype.toString.call(n) === '[object Object]'
null
cheque, porqueObject.prototype.toString.call(null) === '[object Null]'
Me pediram para fornecer mais detalhes. A maneira mais limpa e compreensível de verificar se nossa variável é um objeto
typeof myVar
. Retorna uma string com um tipo (por exemplo"object"
,"undefined"
).Infelizmente, Array e null também têm um tipo
object
. Para pegar apenas objetos reais, é necessário verificar a cadeia de herança usando oinstanceof
operador. Ele eliminará nulo, mas a Matriz possui Objeto na cadeia de herança.Então a solução é:
fonte
/./ instanceof Object //true
Um pouco tarde ... para "objetos simples" (quero dizer, como {'x': 5, 'y': 7}) eu tenho esse pequeno trecho:
Ele gera a próxima saída:
Sempre funciona para mim. If retornará "true" apenas se o tipo de "o" for "objeto", mas nenhum nulo, matriz ou função. :)
fonte
O lodash possui o isPlainObject , que pode ser o que muitos que acessam esta página estão procurando. Retorna false quando fornece uma função ou matriz.
fonte
_.isObject
que corresponde ao que JS considera um objeto. Mas o que eu normalmente preciso é diferenciar entre, por exemplo, um literal de objeto e uma matriz, que é exatamente o que_.isPlainObject
me permite fazer.Isso vai funcionar. É uma função que retorna verdadeiro, falso ou possivelmente nulo.
fonte
null
o resultado do teste final em vez defalse
. Consulte Quando devo editar o código?Como parece haver muita confusão sobre como lidar com esse problema corretamente, deixarei meus 2 centavos (esta resposta é compatível com as especificações e produz resultados corretos em todas as circunstâncias):
Teste de primitivos:
undefined
null
boolean
string
number
Um objeto não é um primitivo:
Ou alternativamente:
Teste para qualquer matriz:
Teste para objeto excluindo:
Date
RegExp
Boolean
Number
String
Function
qualquer matrizfonte
Quando tudo mais falha, eu uso isso:
fonte
item.constructor === Object
?null
lança uma exceçãoUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
ou por causa deconstructor.name
?A biblioteca funcional Ramda tem uma função maravilhosa para detectar tipos de JavaScript.
Parafraseando a função completa :
Eu tive que rir quando percebi como a solução era simples e bonita.
Exemplo de uso da documentação do Ramda :
fonte
Depois de ler e experimentar um monte de implementações, tenho notado que muito poucas pessoas tentam buscar por valores como
JSON
,Math
,document
ou objetos com correntes protótipo mais de 1 passo.Em vez de verificar o
typeof
variável e remover os casos extremos, pensei que seria melhor se a verificação fosse mantida o mais simples possível para evitar refatorar quando houver novos primitivos ou objetos nativos adicionados que sejam registrados comotypeof
'object 'Afinal, o
typeof
operador dirá se algo é um objeto para JavaScript , mas a definição de objeto de JavaScript é muito ampla para a maioria dos cenários do mundo real (por exemplotypeof null === 'object'
). Abaixo está uma função que determina se a variávelv
é um objeto repetindo essencialmente duas verificações:v
for'[object Object]'
.Eu queria que o resultado da função fosse exatamente como os logs abaixo, então esse é o único critério de "objetividade" com o qual acabei. Se falhar, a função retornará falso imediatamente.
v
é substituído pelo próximo protótipo da cadeia porv = Object.getPrototypeOf(v)
, mas também é avaliado diretamente depois. Quando o novo valor dev
énull
, significa que todo protótipo, incluindo o protótipo raiz (que poderia muito bem ter sido o único protótipo dentro da cadeia) passou na verificação no loop while e podemos retornar true. Caso contrário, uma nova iteração será iniciada.fonte
fonte
value
fornull
isso lançará um erro ...false
para o objetoObject.assign({}, {constructor: null})
.Se desejar explicitamente verificar se o valor fornecido é
{}
.fonte
!!obj
é uma abreviação para verificar seobj
é verdade (para filtrarnull
)fonte
É uma pergunta antiga, mas pensamos em deixar isso aqui. A maioria das pessoas está verificando se a variável está
{}
significando um valor-chave emparelhado e não qual é a construção sublinhada que o JavaScript está usando para uma determinada coisa, porque, para ser sincero, tudo o que é JavaScript é um objeto. Então, tirando isso do caminho. Se você fizer...Na maioria das vezes, o que queremos é saber se temos um objeto de recurso de uma API ou nossa chamada de banco de dados retornada do ORM. Podemos então testar se não é um
Array
, nãonull
é, não é typeof'function'
e é umObject
fonte
true
paranew Date()
new Date()
O que eu gosto de usar é este
Acho que, na maioria dos casos, uma Data deve passar na verificação como um Objeto, para não filtrar as datas.
fonte
Eu encontrei uma maneira "nova" de fazer exatamente esse tipo de verificação de tipo nesta pergunta do SO: Por que instanceof retorna false para alguns literais?
a partir disso, criei uma função para verificação de tipo da seguinte maneira:
então você pode fazer:
isso é testado no Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43
editar:
se você também deseja verificar se uma variável é nula ou indefinida, você pode usar isso:
atualização do comentário do inanc: desafio aceito: D
se você quiser perder objetos de comparação, tente desta maneira:
Dessa forma, você pode fazer como o comentário de inanc:
ou
fonte
instanceof
para verificar se há objetos. Ainda assim, essa não é uma ciência exata.new Foo()
retorna umFoo
objeto, mesmo quenew String()
retorna umString
objeto, ounew Date()
retorna umDate
objeto, você pode fazerFoo = function(){}; isVarTypeOf(new Foo(), Foo);
também