Como determinar se um objeto tem uma determinada propriedade em JavaScript

311

Como posso determinar se um objeto xtem uma propriedade definida y, independentemente do valor de x.y?

Atualmente estou usando

if (typeof(x.y) !== 'undefined')

mas isso parece um pouco desajeitado. Existe uma maneira melhor?

royhowie
fonte

Respostas:

584

O objeto tem propriedade:

Se você estiver testando propriedades que estão no próprio objeto (que não fazem parte de sua cadeia de protótipos), poderá usar .hasOwnProperty():

if (x.hasOwnProperty('y')) { 
  // ......
}

O objeto ou seu protótipo possui uma propriedade:

Você pode usar o inoperador para testar propriedades herdadas também.

if ('y' in x) {
  // ......
}
gnarf
fonte
23
Ou ainda melhor - Object.prototype.hasOwnProperty.call(x, 'y'), de modo que propriedade chamada "hasOwnProperty" não seria conflito com processo de inspeção;)
kangax
4
Ou ainda mais curto - {}.hasOwnProperty.call(x, 'y').
precisa saber é
78

Se você quiser saber se o objeto contém fisicamente a resposta da propriedade @ gnarf,hasOwnProperty fará o trabalho.

Se você deseja saber se a propriedade existe em algum lugar, no próprio objeto ou na cadeia de protótipos, você pode usar o inoperador .

if ('prop' in obj) {
  // ...
}

Por exemplo.:

var obj = {};

'toString' in obj == true; // inherited from Object.prototype
obj.hasOwnProperty('toString') == false; // doesn't contains it physically
CMS
fonte
18

Underscore.js ou Lodash

if (_.has(x, "y")) ...

:)

nackjicholson
fonte
Não. É apenas um apelido para Object.prototype.hasOwnProperty.call(x, "y"). Para arrays Eu acho que você pode querer Array.prototype.indexOf, _.indexOfou_.contains
nackjicholson
13

Você pode aparar isso um pouco assim:

if ( x.y !== undefined ) ...
jpsimons
fonte
15
Isso falharia com #x = {y:undefined}
1212 James James
20
Alguém precisa distinguir entre "não definido" e "definido para ser indefinido?"
Jpsimons
16
@darkporter eu faço às vezes;)
mmm
6

Um recurso do meu código original

if ( typeof(x.y) != 'undefined' ) ...

o que pode ser útil em algumas situações é que é seguro usar se xexiste ou não. Com qualquer um dos métodos na resposta do gnarf, deve-se primeiro testar xse há alguma dúvida se ele existe.

Portanto, talvez todos os três métodos tenham um lugar na mochila de truques.


fonte
Você sempre pode usar (x && x.hasOwnProperty('y'))or(x && 'y' in x)
gnarf
Concordo, o teste para x deve ser um caso separado por si só. Também produz melhores relatórios de erros.
b01
Isso falhou para mim. Se x é indefinido, em seguida, typeof (xy) retorna uma ReferenceErrorvez que a string 'indefinido'
Craig
1

Como a pergunta era sobre clunkiness da verificação de propriedades, e um caso regular para validar objetos de opções de argumentos de função, pensei em mencionar uma maneira curta e livre de biblioteca de testar a existência de várias propriedades. Exoneração de responsabilidade: Requer o ECMAScript 5 (mas o IMO que ainda estiver usando o IE8 merece uma web quebrada).

function f(opts) {
  if(!["req1","req2"].every(opts.hasOwnProperty, opts)) {
      throw new Error("IllegalArgumentException");
  }
  alert("ok");
}
f({req1: 123});  // error
f({req1: 123, req2: 456});  // ok
stt
fonte
-2

Por que não simplesmente:

if (typeof myObject.myProperty == "undefined") alert("myProperty is not defined!");

Ou se você espera um tipo específico:

if (typeof myObject.myProperty != "string") alert("myProperty has wrong type or does not exist!");
cúpula
fonte
1
Porque é ruim ler e não digitar estrito. Devo perguntar-lhe: por que não simplesmente x.hasOwnProperty('y')?
Fabian Picone