Como verificar se o objeto tem alguma propriedade em JavaScript?

168

Supondo que eu declaro

var ad = {}; 

Como posso verificar se este objeto contém propriedades definidas pelo usuário?

Ricky
fonte

Respostas:

86

Você pode percorrer as propriedades do seu objeto da seguinte maneira:

for(var prop in ad) {
    if (ad.hasOwnProperty(prop)) {
        // handle prop as required
    }
}

É importante usar o hasOwnProperty()método para determinar se o objeto tem a propriedade especificada como uma propriedade direta e não herdada da cadeia de protótipos do objeto.

Editar

Dos comentários: você pode colocar esse código em uma função e fazê-lo retornar falso assim que chegar à parte em que há o comentário

Teste de performance

Test Of Object.Keys vs For..In Ao testar qualquer propriedade

Daniel Vassallo
fonte
2
Oi Daniel, na verdade, estou procurando um dispositivo para verificar se um objeto contém propriedades definidas pelo usuário ou não. Não para verificar se existe uma propriedade específica.
Ricky
7
@ Ricky: Você pode colocar esse código em uma função e fazê-lo retornar falso assim que chegar à parte em que houver o comentário.
Daniel Vassallo
8
Hoje em dia, acho que o uso Object.keysseria o mais fácil: var a = [1,2,3];a.something=4;console.log(Object.keys(a))como ele já faz parte do ECMA 5, é possível reduzi-lo com segurança: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
HMR
2
Observe que "atualmente" no ES5, objetos nativos podem ter propriedades próprias não enumeráveis, por exemplo Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'}).
RobG
2
Esta solução é uma maneira de verificar se existem chaves , mas a resposta verdadeira, eficiente e mais correta está abaixo, usando Object.keys (x) .length. Você não precisa fazer sua própria função, uma já existe!
Dudewad
196

Você pode usar o Object.keysmétodo interno para obter uma lista de chaves em um objeto e testar seu comprimento.

var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values

if(Object.keys(x).length > 0){
 // Your code here if x has some properties  
}
Dhaval Chaudhary
fonte
14
Isso aqui é a resposta correta. A resposta aceita acima é uma solução alternativa e é mais cara do que apenas verificar o número de chaves; isso faz muito mais sentido .
Dudewad
6
Object.keys ("mystring"); produz chaves também, o que eu acho indesejável. Esta resposta está incompleta na minha opinião.
Mike de Klerk 02/09
2
@MikedeKlerk, por favor, leia com atenção, não é Object.keys ("mystring"); é Object.keys (objectVariableName) que retornará a matriz de todas as chaves no objeto. ex: {'x': 'abc', 'y': 'def'} será ['x', 'y']
Dhaval Chaudhary
3
@DhavalChaudhary Obrigado pela sua resposta ao meu comentário. Quando tento esse código var str = "MyString"; Object.keys(str);, o console gera 8 teclas, de 0 a 7, para cada caractere. Ou ainda não entendi a resposta.
Mike de Klerk
6
@MikedeKlerk, mas é apenas a solução para objetos, não para strings pls, consulte a pergunta.
Dhaval Chaudhary
111

Que tal criar uma função simples?

function isEmptyObject(obj) {
  for(var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
  }
  return true;
}

isEmptyObject({}); // true
isEmptyObject({foo:'bar'});  // false

A hasOwnPropertychamada de método diretamente no Object.prototypeé apenas para adicionar um pouco mais de segurança , imagine o seguinte usando uma obj.hasOwnProperty(...)chamada normal :

isEmptyObject({hasOwnProperty:'boom'});  // false

Nota: (para o futuro) O método acima baseia-se na for...indeclaração, e esta itera apenas as propriedades enumeráveis , no ECMAScript Standard (3ª edição) atualmente mais implementado atualmente, o programador não tem como criar propriedades não enumeráveis .

No entanto, isso mudou agora com o ECMAScript 5th Edition , e somos capazes de criar propriedades não enumeráveis, não graváveis ​​ou não excluídas, para que o método acima possa falhar , por exemplo:

var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal', 
  enumerable: false,
  writable: true,
  configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!

Uma solução ECMAScript 5 para esse problema seria:

function isEmptyObject(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

O Object.getOwnPropertyNamesmétodo retorna e Arraycontém os nomes de todas as propriedades próprias de um objeto, enumeráveis ​​ou não ; esse método está sendo implementado agora pelos fornecedores de navegadores, já está no Chrome 5 Beta e nas últimas versões do WebKit Nightly Builds.

Object.defineProperty também está disponível nesses navegadores e nas versões mais recentes do Firefox 3.7 Alpha.

CMS
fonte
1
Qual é a vantagem de Object.prototype.hasOwnProperty.call (obj, prop) sobre obj.hasOwnProperty (prop)?
Casey Chu
3
@ Casey, editado, se um objeto substitui a hasOwnPropertypropriedade, a função pode falhar ... Eu sei que sou um pouco paranóica ... mas às vezes você não sabe em que tipo de ambiente seu código será usado, mas você sabe o método que deseja usar ...
CMS
2
+1 por responder a esta pergunta ... e outras perguntas do futuro! :)
Daniel Vassallo
1
Observe que também existe um bug no IE, onde se você tiver uma propriedade com um nome que corresponda a uma propriedade não enumerável Object.prototype, ela não será enumerada por for...in. Então isEmptyObject({toString:1})vai falhar. Esta é uma das razões infelizes você não pode bastante usam Objectcomo um mapeamento de uso geral.
bobince
1
@ MichaelMartin-Smucker - as chaves retornam apenas propriedades próprias enumeráveis, portanto não são adequadas aqui.
RobG
58

Com o jQuery você pode usar:

$.isEmptyObject(obj); // Returns: Boolean

A partir do jQuery 1.4, esse método verifica as propriedades no próprio objeto e as propriedades herdadas dos protótipos (na medida em que ele não usa hasOwnProperty).

Com o ECMAScript 5th Edition em navegadores modernos (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +), você pode usar o método Object.keys incorporado :

var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;

Ou JavaScript antigo simples:

var isEmpty = function(obj) {
               for(var p in obj){
                  return false;
               }
               return true;
            };
kayz1
fonte
13

Se você estiver usando underscore.js, poderá usar a função _.isEmpty :

var obj = {};
var emptyObject = _.isEmpty(obj);
Coelho áspero
fonte
1
Apenas para quem passa, este não é um método dedicado a objetos. _.isEmpty([]) // true Certifique-se de verificar primeiro: stackoverflow.com/a/22482737/1922747
djv
11

Se você estiver disposto a usar o lodash , poderá usar o somemétodo

_.some(obj) // returns true or false

Veja este pequeno exemplo de jsbin

sfs
fonte
var x = [1,2] // true
djv 30/12/2015
@damionjn Adicionei seu código ao exemplo. Eu entendo o seu argumento com a matriz retornando a resposta errada, mas o OP inicialmente declarou uma variável como um objeto, por isso acredito que não há problema em assumir isso. Há uma resposta acima, que usa o método isEmpty de sublinhados (o lodash tem o mesmo método). Essa resposta tem exatamente o mesmo problema. Se você der ao isEmpty um array não vazio, também obterá o resultado errado.
sfs
É justo, mas devemos fornecer respostas com todas as bases abordadas para garantir as melhores práticas. Você está certo, passei direto pela resposta dele sem nenhuma crítica. Apenas para quem passa, este não é um método dedicado a objetos. _.some([1, 2]) // true Certifique-se de verificar primeiro: stackoverflow.com/a/13356338/1922747
djv
5
for (var hasProperties in ad) break;
if (hasProperties)
    ... // ad has properties

Se você precisar estar seguro e verificar os protótipos de objetos (eles são adicionados por determinadas bibliotecas e não existem por padrão):

var hasProperties = false;
for (var x in ad) {
    if (ad.hasOwnProperty(x)) {
        hasProperties = true;
        break;
    }
}
if (hasProperties)
    ... // ad has properties
Casey Chu
fonte
1
na sua solução, não há filtragem de propriedades de protótipo indesejadas, o que significa que pode estar se comportando mal ao usar uma biblioteca como Prototype.js ou um usuário inexperiente adicionou propriedades de protótipo adicionais ao objeto. Confira a solução Daniels nesta página.
Joscha
Você não precisa usar uma biblioteca ou ser inexperiente para estender o protótipo de um objeto. Alguns programadores experientes fazem isso o tempo todo.
Alsciende
2
for(var memberName in ad)
{
  //Member Name: memberName
  //Member Value: ad[memberName]
}

Membro significa propriedade de membro, variável de membro, como você quiser chamá-lo> _>

O código acima retornará TUDO, incluindo toString ... Se você quiser apenas ver se o protótipo do objeto foi estendido:

var dummyObj = {};  
for(var memberName in ad)
{
  if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
  //Member Name: memberName
  //Member Value: ad[memberName]

}

Nota A: Verificamos se o membro do objeto fictício tem o mesmo tipo que o membro do objeto de teste. Se for uma extensão, o tipo de membro do dummyobject deve ser "indefinido"

Warty
fonte
Oi, posso apenas saber se um objeto contém propriedades ou não? Obrigado
Ricky
na sua solução, não há filtragem para propriedades de protótipo indesejadas, o que significa que pode estar se comportando mal ao usar uma biblioteca como Prototype.js ou um usuário inexperiente adicionou propriedades de protótipo adicionais ao objeto.
21310
confira a solução Daniels nesta página - é menos propensa a erros!
Joscha
2
Seu primeiro bloco de código não cobre nada disso. o segundo bloco de código se comporta mal se eu adicionar uma variável ao objeto "ad" que é indefinido. Realmente, confira a resposta de Daniels, é a única correta e rápida, pois usa uma implementação nativa chamada "hasOwnProperty".
Joscha
@ Ricky: Se você quiser verificar se um objeto contém propriedades, basta usar o exemplo da minha resposta: stackoverflow.com/questions/2673121/… . Se o código atingir o comentário, seu objeto não terá propriedades diretas. Se não, seria.
21710 Daniel Vassallo
2
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist

Simples, funciona em todos os navegadores e, embora tecnicamente seja um loop para todas as chaves do objeto, NÃO repassa todas elas ... ou há 0 e o loop não roda ou há algumas e quebra após a primeira um (porque tudo o que estamos verificando é se há QUALQUER ... então por que continuar?)

Jimbo Jonny
fonte
1

Resposta muito tardia, mas é assim que você pode lidar com isso com protótipos.

Array.prototype.Any = function(func) {
    return this.some(func || function(x) { return x });
}

Object.prototype.IsAny = function() {
    return Object.keys(this).Any();
}
Lucro
fonte
0

Quando a certeza de que o objeto é definido pelo usuário, a maneira mais fácil de determinar se o UDO está vazio é o seguinte código:

isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};

Embora esse método seja (por natureza) dedutivo, é o mais rápido e o mais rápido possível.

a={};
isEmpty(a) >> true

a.b=1
isEmpty(a) >> false 

ps:! não o use em objetos definidos pelo navegador.

Bill the Lizard
fonte
... retornar 0; retornar 1}; seria o mesmo?
commonpike
1
@pike não, retorne! 1; retorne! 0 é o mesmo que retorne false; retorne verdadeiro #
Christophe
0

Resposta tardia, mas algumas estruturas manipulam objetos como enumeráveis. Portanto, o bob.js pode fazer o seguinte:

var objToTest = {};
var propertyCount = bob.collections.extend(objToTest).count();
Tengiz
fonte
0

Você pode usar o seguinte:

Double bang !! pesquisa de propriedade

var a = !![]; // true
var a = !!null; // false

hasOwnProperty Isso é algo que eu costumava usar:

var myObject = {
  name: 'John',
  address: null
};
if (myObject.hasOwnProperty('address')) { // true
  // do something if it exists.
}

No entanto, o JavaScript decidiu não proteger o nome do método, para que pudesse ser adulterado.

var myObject = {
  hasOwnProperty: 'I will populate it myself!'
};

prop em myObject

var myObject = {
  name: 'John',
  address: null,
  developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.

tipo de

if (typeof myObject.name !== 'undefined') {
  // do something
}

No entanto, ele não verifica se há nulo.

Eu acho que esse é o melhor caminho.

no operador

var myObject = {
  name: 'John',
  address: null
};

if('name' in myObject) {
  console.log("Name exists in myObject");
}else{
  console.log("Name does not exist in myObject");
}

resultado:

O nome existe em myObject

Aqui está um link que entra em mais detalhes sobre o operador in: Determinando se existe uma propriedade de objeto

James Drinkard
fonte
0

Função ES6

/**
 * Returns true if an object is empty.
 * @param  {*} obj the object to test
 * @return {boolean} returns true if object is empty, otherwise returns false
 */
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0

Exemplos:


let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false
Sébastien
fonte
-1

Que tal agora?

var obj = {},
var isEmpty = !obj;
var hasContent = !!obj
Peter Toth
fonte
Esta resposta não responde à pergunta. O OP está perguntando se um objeto contém propriedades definidas pelo usuário - sua resposta verifica se o próprio objeto será convertido em um valor falso booleano.
Jasmonate
... e também percebi depois que James já incluiu essa opção em sua resposta. Desculpem rapazes.
Peter Toth