Como faço para acessar as propriedades de um objeto javascript se não souber os nomes?

124

Digamos que você tenha um objeto javascript como este:

var data = { foo: 'bar', baz: 'quux' };

Você pode acessar as propriedades pelo nome da propriedade:

var foo = data.foo;
var baz = data["baz"];

Mas é possível obter esses valores se você não souber o nome das propriedades? A natureza desordenada dessas propriedades torna impossível diferenciá-las?

No meu caso, estou pensando especificamente em uma situação em que uma função precisa aceitar uma série de pares nome-valor, mas os nomes das propriedades podem mudar.

Meu pensamento sobre como fazer isso até agora é passar os nomes das propriedades para a função junto com os dados, mas isso parece um hack. Eu preferiria fazer isso com introspecção, se possível.

Adam Lassek
fonte

Respostas:

144

Você pode percorrer chaves como esta:

for (var key in data) {
  console.log(key);
}

Isso registra "Nome" e "Valor".

Se você tiver um tipo de objeto mais complexo (não apenas um objeto simples de hash, como na pergunta original), desejará percorrer apenas as chaves que pertencem ao próprio objeto, em vez das chaves no protótipo do objeto :

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    console.log(key);
  }
}

Como você observou, não é garantido que as chaves estejam em uma ordem específica. Observe como isso difere do seguinte:

for each (var value in data) {
  console.log(value);
}

Este exemplo faz um loop através dos valores, portanto, registraria Property Namee 0. Nota: a for eachsintaxe é suportada apenas no Firefox, mas não em outros navegadores.

Se o seu navegador de destino suportar o ES5 ou o seu site incluir es5-shim.js(recomendado), você também poderá usar Object.keys:

var data = { Name: 'Property Name', Value: '0' };
console.log(Object.keys(data)); // => ["Name", "Value"]

e faça um loop com Array.prototype.forEach:

Object.keys(data).forEach(function (key) {
  console.log(data[key]);
});
// => Logs "Property Name", 0
Ron DeVera
fonte
Você acabou de inventar essa última e realmente se safou? Bem feito ... =)
nickl-
Isso existe no Firefox ( docs ), mas é justo dizer que não é universal. Vou atualizar a resposta para mencionar isso.
Ron DeVera 26/09/12
28
btw alerta é uma má maneira de coisas de depuração, tente console.log
StackOverflowed
Essa foi a melhor resposta quando a pergunta foi feita, mas estou removendo a marca de seleção porque versões posteriores do JS forneceram ferramentas melhores.
precisa saber é o seguinte
65

As versões antigas do JavaScript (<ES5) requerem o uso de um for..inloop:

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    // do something with key
  }
}

O ES5 apresenta Object.keys e Array # forEach, o que facilita um pouco:

var data = { foo: 'bar', baz: 'quux' };

Object.keys(data); // ['foo', 'baz']
Object.keys(data).map(function(key){ return data[key] }) // ['bar', 'quux']
Object.keys(data).forEach(function (key) {
  // do something with data[key]
});

O ES2017 apresenta Object.valuese Object.entries.

Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]
Adam Lassek
fonte
1
Agora, isso realmente responde à pergunta, muito bem @Adam Lassek, muito bem feito.
precisa saber é o seguinte
É enganoso usar 'nome' e 'valor' como chaves de objeto. Esta função retorna apenas as chaves em uma lista, não os valores. {nome1: 'valor1', nome2: 'valor2'} evitará confusão para iniciantes. Object.keys (dados); // ['name1', 'name2']
James Nicholson
2
@JamesNicholson Concordo, editado para ser menos confuso.
precisa saber é o seguinte
10
for(var property in data) {
    alert(property);
}
karim79
fonte
4

Muitas vezes, você deseja examinar as propriedades específicas de uma instância de um objeto, sem todos os métodos e propriedades de protótipo compartilhados:

 Obj.prototype.toString= function(){
        var A= [];
        for(var p in this){
            if(this.hasOwnProperty(p)){
                A[A.length]= p+'='+this[p];
            }
        }

    return A.join(', ');
}
Kennebec
fonte
3
function getDetailedObject(inputObject) {
    var detailedObject = {}, properties;

    do {
        properties = Object.getOwnPropertyNames( inputObject );
        for (var o in properties) {
            detailedObject[properties[o]] = inputObject[properties[o]];
        }
    } while ( inputObject = Object.getPrototypeOf( inputObject ) );

    return detailedObject;
}

Isso obterá todas as propriedades e seus valores (herdados ou próprios, enumeráveis ​​ou não) em um novo objeto. o objeto original está intocado. Agora, um novo objeto pode ser percorrido usando

var obj = { 'b': '4' }; //example object
var detailedObject = getDetailedObject(obj);
for(var o in detailedObject) {
    console.log('key: ' + o + '   value: ' + detailedObject[o]);
}
Shishir Arora
fonte
1
var obj = {
 a: [1, 3, 4],
 b: 2,
 c: ['hi', 'there']
 }
for(let r in obj){  //for in loop iterates all properties in an object
 console.log(r) ;  //print all properties in sequence
 console.log(obj[r]);//print all properties values
}
Mayank_VK
fonte
onde esta resposta fornece o que é exigido pelo OP, mas uma pequena descrição do que você está fazendo e por que o OP deve usá-lo seria bom, também não se esqueça de .hasOwnProperty()usar quando for para iterar um objeto.
Muhammad Omer Aslam,
Obrigado, eu concordo que .hasOwnProperty () itera o objeto, mas itera para verificar uma condição, no entanto, usando-a, não podemos imprimir todas as propriedades de um objeto. Corrija-me se estiver errado.
Mayank_VK
O hasOwnProperty()método retorna um booleanindicando se o objeto tem a propriedade especificada como sua própria propriedade (em vez de herdá-lo) . veja este exemplo
Muhammad Omer Aslam
1

Você pode usar Object.keys () , "que retorna uma matriz dos nomes de propriedades enumeráveis ​​de um determinado objeto, na mesma ordem que obtemos com um loop normal".

Você pode usar qualquer objeto no lugar de stats:

var stats = {
  a: 3,
  b: 6,
  d: 7,
  erijgolekngo: 35
}
/*  this is the answer here  */
for (var key in Object.keys(stats)) {
  var t = Object.keys(stats)[key];
  console.log(t + " value =: " + stats[t]);
}

Cloid J. Green
fonte
Você poderia adicionar mais explicações?
precisa
Object.keys( stats )[key]não faz sentido, sempre será undefined.
Adam Lassek
-2
var attr, object_information='';

for(attr in object){

      //Get names and values of propertys with style (name : value)
      object_information += attr + ' : ' + object[attr] + '\n'; 

   }


alert(object_information); //Show all Object
isaax2
fonte
Isso não acrescenta nada à resposta aceita e apresenta as informações da maneira menos útil possível. E não conta para propriedades herdadas.
precisa saber é o seguinte