Como verifico se um objeto tem uma propriedade específica em JavaScript?
Considerar:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Essa é a melhor maneira de fazer isso?
javascript
sheats
fonte
fonte
in
ehasOwnProperty
saiu muito mais lento que os outros para mim (98% mais lento). Não estou surpreso porhasOwnProperty
ser mais lento, mas estou surpresoin
.Respostas:
Estou realmente confuso com as respostas que foram dadas - a maioria delas é totalmente incorreta. Obviamente, você pode ter propriedades de objetos que tenham valores indefinidos, nulos ou falsos. Portanto, basta reduzir a verificação da propriedade para
typeof this[property]
, ou pior ainda,x.key
fornecer resultados completamente enganosos.Depende do que você está procurando. Se você deseja saber se um objeto contém fisicamente uma propriedade (e não vem de algum lugar na cadeia de protótipos), então
object.hasOwnProperty
é o caminho a seguir. Todos os navegadores modernos são compatíveis. (Faltava nas versões mais antigas do Safari - 2.0.1 e mais antigas - mas essas versões do navegador raramente são mais usadas.)Se o que você está procurando é se um objeto tem uma propriedade iterável (quando você iterar sobre as propriedades do objeto, ele aparecerá), então o procedimento:
prop in object
dará o efeito desejado.Como usar
hasOwnProperty
é provavelmente o que você deseja, e considerando que você pode querer um método de fallback, apresento a você a seguinte solução:A descrição acima é uma solução funcional, em vários navegadores,
hasOwnProperty
com uma ressalva: não é possível distinguir entre os casos em que uma propriedade idêntica está no protótipo e na instância - apenas assume que é proveniente do protótipo. Você pode mudar para ser mais branda ou estrita, com base na sua situação, mas, no mínimo, isso deve ser mais útil.fonte
var w = opts.w || 100;
. Mas se você gosta de algo como uma biblioteca, pode precisar ir um pouco mais longe em algumas partes.__proto__
para nulo? Simples impl:function hasOwnProperty(obj, prop) { var temp = obj.__proto__; obj.__proto__ = null; var ret = prop in obj; obj.__proto__ = temp; return ret; }
(Caso comobj.constructor.prototype
deve ser adicionado).__proto__
não é padrão e não funciona em alguns navegadores mais antigos. E mesmo com a recente adição doObject.getPrototypeOf
padrão, você ainda não pode alterar o protótipo de um objeto existente.for(prop in object)
loop itera apenas propriedades enumeráveis. No entanto,prop in object
verifica seobject
a propriedade estáprop
em algum lugar da cadeia prototípica, independentemente de ser enumerável ou não.Com
Underscore.js
ou ( melhor ainda )lodash
:Que chama
Object.prototype.hasOwnProperty
, mas (a) é mais curto para digitar e (b) usa "uma referência segura parahasOwnProperty
" (ou seja, funciona mesmo sehasOwnProperty
for sobrescrito).Em particular, lodash define
_.has
como:fonte
npm install lodash.has
expor um módulo npm com apenas umahas
função que compila até 175 bytes quando minificada. Também é interessantelodash.has/index.js
ver como funciona uma biblioteca muito popular e confiável.lodash
's versões trabalha com isso:.has(undefined, 'someKey') => false
enquantounderscore
retornosundefined
lodash
como "mais uma" dependência: é uma biblioteca bastante comum (se não a mais comum) para esse tipo de coisa. Divirta-se reinventando a roda.A respeito?
fonte
in
operador ou não. Observe também que oin
operador possui excelente suporte ao navegadorIE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+
stackoverflow.com/questions/2920765/…in
também verifica as propriedades do protótipo, enquantohasOwnProperty
itera apenas as propriedades definidas pelo usuário. Referência: developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…'key' in x
fazer o trabalho com arrays. Prova: stackoverflow.com/questions/33592385/…Nota : hoje em dia é amplamente obsoleto graças ao modo estrito, e
hasOwnProperty
. A solução correta é usar o modo estrito e verificar a presença de uma propriedade usandoobj.hasOwnProperty
. Essa resposta é anterior a essas duas coisas, pelo menos como amplamente implementada (sim, é tão antiga). Tome o seguinte como uma nota histórica.Lembre-se de que
undefined
(infelizmente) não é uma palavra reservada em JavaScript se você não estiver usando o modo estrito. Portanto, alguém (obviamente alguém) poderia ter a grande idéia de redefini-lo, quebrando seu código.Um método mais robusto é, portanto, o seguinte:
Por outro lado, esse método é muito mais detalhado e também mais lento. : - /
Uma alternativa comum é garantir que isso
undefined
seja realmente indefinido, por exemplo, colocando o código em uma função que aceita um parâmetro adicional, chamadoundefined
, que não recebe um valor. Para garantir que não seja passado um valor, você mesmo pode chamá-lo imediatamente, por exemplo:fonte
void 0
é definido para devolver o canônicoundefined
, alguém poderia fazerx.attribute !== void 0
?(function (undefined) { // undefined is actually undefined here })();
Armin Ronacher parece já ter me vencido , mas:
Uma solução mais segura, mas mais lenta, como apontado por Konrad Rudolph e Armin Ronacher, seria:
fonte
x.hasOwnProperty('toString') === true;
Object.prototype
já possui um built-in, corretohasOwnProperty
. Sobrescrevê-lo com uma implementação incorreta (1. As propriedades podem ter o valorundefined
, 2. Isso fornecerá falsos positivos para propriedades herdadas) é apenas uma péssima idéia. Respostas incorretas podem e devem ser excluídas. Não sei se você poderia fazer isso em setembro de 2008, quando viu a resposta de Resig , então, comentando, sugira fazê-lo agora.Você pode usar o
in
operador para verificar se a propriedade existe em um objeto:Você também pode percorrer todas as propriedades do objeto usando um
for - in
loop e, em seguida, verificar a propriedade específica:Você deve considerar se essa propriedade de objeto é enumerável ou não, porque propriedades não enumeráveis não serão exibidas em um
for-in
loop. Além disso, se a propriedade enumerável estiver sombreando uma propriedade não enumerável do protótipo, ela não será exibida no Internet Explorer 8 e versões anteriores.Se você desejar uma lista de todas as propriedades da instância, sejam enumeráveis ou não, poderá usar
Isso retornará uma matriz de nomes de todas as propriedades que existem em um objeto.
Por fim, você pode usar o operador typeof para verificar diretamente o tipo de dados da propriedade do objeto:
Se a propriedade não existir no objeto, ela retornará a string indefinida. Caso contrário, ele retornará o tipo de propriedade apropriado. No entanto, observe que essa nem sempre é uma maneira válida de verificar se um objeto tem uma propriedade ou não, porque você pode ter uma propriedade definida como indefinida; nesse caso, o uso
typeof x.key
ainda retornará true (mesmo que a chave ainda esteja no objeto).Atualização: você pode verificar se existe uma propriedade comparando com a propriedade javascript indefinida
Isso deve funcionar, a menos que a chave tenha sido definida especificamente
undefined
no objeto xfonte
Vamos cortar alguma confusão aqui. Primeiro, vamos simplificar assumindo que
hasOwnProperty
já existe; isso se aplica à grande maioria dos navegadores atuais em uso.hasOwnProperty
retorna true se o nome do atributo que é passado para ele tiver sido adicionado ao objeto. É totalmente independente do valor real atribuído a ele, que pode ser exatamenteundefined
.Conseqüentemente:
Contudo:
O problema é o que acontece quando um objeto na cadeia de protótipos tem um atributo com o valor de indefinido?
hasOwnProperty
será falso por isso, e assim será!== undefined
. No entanto,for..in
ainda o listará na enumeração.A conclusão é que não existe uma maneira entre navegadores (já que o Internet Explorer não expõe
__prototype__
) para determinar que um identificador específico não foi anexado a um objeto ou qualquer coisa em sua cadeia de protótipos.fonte
Se você estiver procurando por uma propriedade, então "NÃO". Você quer:
Em geral, você não deve se importar se a propriedade vem ou não do protótipo ou do objeto.
No entanto, como você usou 'key' em seu código de exemplo, parece que você está tratando o objeto como um hash. Nesse caso, sua resposta faria sentido. Todas as chaves de hashes seriam propriedades no objeto e você evita as propriedades extras contribuídas pelo protótipo.
A resposta de John Resig foi muito abrangente, mas achei que não estava claro. Especialmente com quando usar "'prop' em obj".
fonte
in
operador possui excelente suporte ao navegadorIE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+
stackoverflow.com/questions/2920765/…in
operador: "ele trabalha com 'objetos' em sentido estrito, declarado como {} ou criado usando o construtor, não aceita matrizes ou primitivas. Não que o OP o tenha exigido, mas algumas outras respostas são apresentadas técnicas que são mais ampla (trabalho com matrizes, cordas etc.)"Para testar objetos simples, use:
if (obj[x] !== undefined)
Se você não souber que tipo de objeto é usado:
if (obj.hasOwnProperty(x))
Todas as outras opções são mais lentas.
Detalhes
Avaliação de desempenho de 100.000.000 ciclos no Nodejs para as 5 opções sugeridas por outras pessoas aqui:
A avaliação nos diz que, a menos que desejemos especificamente verificar a cadeia de protótipos do objeto e o próprio objeto, não devemos usar a forma comum:
if (X in Obj)...
é entre 2 a 6 vezes mais lenta, dependendo do caso de usoResumindo, se seu Obj não é necessariamente um objeto simples e você deseja evitar verificar a cadeia de protótipos do objeto e garantir que x seja de propriedade de Obj diretamente, use 'if (obj.hasOwnProperty (x)) ...'.
Caso contrário, ao usar um objeto simples e não se preocupar com a cadeia de protótipos do objeto, usar
if (typeof(obj[x]) !== 'undefined')...
é a maneira mais segura e rápida.Se você usa um objeto simples como uma tabela de hash e nunca faz nada excêntrico, eu usaria o
if (obj[x])...
que eu acho muito mais legível.Diverta-se.
fonte
Sim, é :) Eu acho que você também pode fazer o
Object.prototype.hasOwnProperty.call(x, 'key')
que também deve funcionar sex
tiver uma propriedade chamadahasOwnProperty
:)Mas isso testa propriedades próprias. Se você deseja verificar se ele possui uma propriedade que também pode ser herdada, você pode usá-lo
typeof x.foo != 'undefined'
.fonte
Porque
falha se
x.key
resolver parafalse
(por exemplo,x.key = ""
).fonte
const x = {key: undefined};
que retornará falso com esta solução, enquantox.hasOwnProperty('key')); // true
eReflect.has(x, 'key')); // true
. A propriedade realmente existe, mas o valor éundefined
.Você também pode usar o
Reflect
objeto ES6 :A documentação no MDN para
Reflect.has
pode ser encontrada aqui .fonte
OK, parece que eu tive a resposta certa, a menos que você não queira propriedades herdadas:
Aqui estão algumas outras opções para incluir propriedades herdadas:
fonte
var x = { key: false };
ox.key
método estaria incorreto.Não faça isso
object.hasOwnProperty(key))
, é muito ruim, porque esses métodos podem estar sombreados por propriedades no objeto em questão - considere{ hasOwnProperty: false }
- ou, o objeto pode ser um objeto nulo(Object.create(null))
.A melhor maneira é fazer
Object.prototype.hasOwnProperty.call(object, key)
ou:fonte
Outra maneira relativamente simples é usar
Object.keys
. Isso retorna um, oarray
que significa que você obtém todos os recursos de uma matriz.Embora estejamos em um mundo com ótimo suporte ao navegador. Como essa pergunta é tão antiga, pensei em adicionar: Isso é seguro para uso a partir do JS v1.8.5
fonte
Object.keys(info).indexOf('someotherthing') !== -1
hasOwnProperty "pode ser usado para determinar se um objeto tem a propriedade especificada como uma propriedade direta desse objeto; diferente do operador in , esse método não verifica a cadeia de protótipos do objeto".
Portanto, provavelmente, para o que parece ser sua pergunta, você não deseja usar o hasOwnProperty, que determina se a propriedade existe como anexada diretamente ao próprio objeto ,.
Se você deseja determinar se a propriedade existe na cadeia de protótipos em que você deseja usar, como:
Eu espero que isso ajude.
fonte
Com risco de redução de votos massiva, aqui está outra opção para um caso específico. :)
Se você deseja testar um membro em um objeto e deseja saber se ele foi definido como algo diferente de:
então você pode usar:
fonte
Solução ECMA Script 6 com reflect. Crie um invólucro como:
fonte
Existe o método "hasOwnProperty" existente no objeto, mas não é recomendável chamar esse método diretamente, porque às vezes o objeto é nulo ou alguma propriedade existe no objeto, como:
{ hasOwnProperty: false }
Então, a melhor maneira seria:
fonte
Você pode usar as seguintes abordagens:
A diferença entre as seguintes abordagens são as seguintes:
fonte
Você precisa usar o método
object.hasOwnProperty(property)
. Retorna true se o objeto possui a propriedade e false se o objeto não possui.fonte
Se a chave que você está verificando estiver armazenada em uma variável , você pode verificá-la assim:
fonte
Por que complicar demais as coisas quando você pode fazer:
Simples e claro para a maioria dos casos ...
fonte
const objectName = { keyname: false };
ele deve retornar true, uma vez quekeyname
é uma propriedade deobjectname
. Mas como o valor é falso, ele retornaria falso com essa lógica.