Como acessar a primeira propriedade de um objeto Javascript?

611

Existe uma maneira elegante de acessar a primeira propriedade de um objeto ...

  1. onde você não sabe o nome de suas propriedades
  2. sem usar um loop como for .. inou jQuery$.each

Por exemplo, preciso acessar o foo1objeto sem saber o nome de foo1:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};
atogle
fonte
1
é provavelmente melhor para transformá-lo em uma matriz primeiro
cregox

Respostas:

1393
var obj = { first: 'someVal' };
obj[Object.keys(obj)[0]]; //returns 'someVal'

Usando isso, você também pode acessar outras propriedades por índices. Esteja ciente! Object.keysa ordem de devolução não é garantida de acordo com o ECMAScript, mas de maneira não oficial pelas principais implementações de navegadores, leia https://stackoverflow.com/a/23202095 para obter detalhes sobre isso.

Grzegorz Kaczan
fonte
25
Você diz que não é o caminho mais rápido. Que caminho seria mais rápido?
T Nguyen
3
Isso não é muito eficiente, pois cria uma matriz inteira de todas as chaves do objeto.
Andrew Mao
9
@T Nguyen eu post-it Se eu soubesse que :)
Grzegorz Kaczan
5
@DavChana - Você teve sua referência configurada incorretamente. O bloco padrão sempre será executado e seu bloco 2 estava vazio, o que significa que o primeiro resultado representa a execução padrão + bloco1 , e o segundo resultado representa apenas o padrão . Aqui está o benchmark correto: http://jsben.ch/#/R9aLQ , mostrando que eles são praticamente iguais (execute o teste várias vezes).
myfunkyside
9
Eu gostaria que first()algo semelhante pudesse lidar com isso.
Fr0zenFyr
113

Experimente o for … inloop e quebre após a primeira iteração:

for (var prop in object) {
    // object[prop]
    break;
}
quiabo
fonte
1
Eu acho que essa é a única opção. Não tenho certeza de que você tenha certeza de que as propriedades serão iteradas em uma ordem previsível / útil. Ou seja, você pode pretender foo1, mas obter foo3. Se as propriedades estiverem numeradas como no exemplo, você poderá comparar uma sequência para verificar o identificador que termina em '1'. Por outro lado, se a ordinalidade é a principal preocupação da coleção, você provavelmente deve usar uma matriz em vez de um objeto.
steamer25
2
Se alguém mais estiver preocupado com o pedido, a maioria dos navegadores se comportará de maneira previsível: stackoverflow.com/questions/280713/…
Flash
6
var prop; para (sustentação no objeto) quebra; // object [prop]
net
12
Resposta antiga, mas. Você pode querer verificar se a propriedade pertence ao objeto. like: for (..) {if (! obj.hasOwnProperty (prop)) continua; .... quebrar; } caso o objeto esteja realmente vazio, ele não percorre o protótipo ou algo assim.
Pgarciacamou
46

Use Object.keyspara obter uma matriz das propriedades em um objeto. Exemplo:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

var keys = Object.keys(example); // => ["foo1", "foo2", "foo3"] (Note: the order here is not reliable)

Documentação e correção entre navegadores fornecidos aqui . Um exemplo de seu uso pode ser encontrado em outra das minhas respostas aqui .

Edit : para maior clareza, eu só quero repetir o que foi afirmado corretamente em outras respostas: a ordem das chaves nos objetos javascript é indefinida.

benekastah
fonte
25

Uma versão de uma regra:

var val = example[function() { for (var k in example) return k }()];
netiul
fonte
2
Às vezes, pode ser arriscado usá-lo for insem verificar, hasOwnPropertypois o objeto contém outros valores indesejados anexados a ele programaticamente, para que você possa obter um resultado indesejado desse snippet. Só porque é curto e limpo, não significa que é seguro ideal.
Javier Cobos
24

Não há uma propriedade "primeira". As chaves do objeto não são ordenadas.

Se você fizer um loop sobre eles (var foo in bar), obterá-os em alguma ordem, mas poderá mudar no futuro (especialmente se você adicionar ou remover outras chaves).

Quentin
fonte
Impressionante. Eu tenho usado um objeto para implementar um mapa que mantém a ordem de inserção. Isso é interrompido quando eu removo um valor, porque a próxima inserção preenche a lacuna. :(
David Harkness
2
a ordem de chave / valor deve ser preservada nas versões mais recentes do JS
Alexander Mills
11

Solução com a biblioteca lodash :

_.find(example) // => {name: "foo1"}

mas não há garantia da ordem de armazenamento interno das propriedades do objeto, pois depende da implementação da VM em javascript.

pocheptsov
fonte
2
Apenas testei isso e não funciona. Ele retorna apenas o valor, não o par chave / valor.
Chris Haines
2
Não há menção na pergunta de que ele deve retornar o par de chave / valor, ele apenas pede o objeto e a resposta aceita faz tanto quanto essa função lodash: retorna o conteúdo da primeira propriedade. Pode não atender às suas necessidades específicas, mas esta resposta está correta com base na pergunta original.
Carrm
Sim faz o trabalho, útil quando você sabe que seu objeto terá apenas um filho objetovar object = { childIndex: { .. } }; var childObject = _.find(Object);
Raja Khoury
9

Não. Um literal de objeto, conforme definido pelo MDC, é:

uma lista de zero ou mais pares de nomes de propriedades e valores associados de um objeto, entre chaves ({}).

Portanto, um literal de objeto não é uma matriz e você pode acessar apenas as propriedades usando o nome explícito ou um forloop usando a inpalavra - chave.

Alex Rozanski
fonte
25
Para outras pessoas, apenas vendo o visto verde nesta resposta, existe outra solução mais abaixo na página, com 350 votos a favor.
redfox05
7

A resposta superior pode gerar toda a matriz e capturar da lista. Aqui está outro atalho eficaz

var obj = { first: 'someVal' };
Object.entries(obj)[0][1] // someVal
kishorekumaru
fonte
3

Isso já foi abordado aqui antes.

O conceito de primeiro não se aplica às propriedades do objeto, e a ordem de um loop for ... in não é garantida pelas especificações, no entanto, na prática, é confiável FIFO, exceto criticamente para o chrome ( relatório de bug ). Tome suas decisões de acordo.

annakata
fonte
3

Eu não recomendo que você use Object.keys, pois não é suportado nas versões antigas do IE. Mas se você realmente precisar disso, poderá usar o código acima para garantir a compatibilidade com versões anteriores:

if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
    hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
    dontEnums = [
      'toString',
      'toLocaleString',
      'valueOf',
      'hasOwnProperty',
      'isPrototypeOf',
      'propertyIsEnumerable',
      'constructor'
    ],
    dontEnumsLength = dontEnums.length;

return function (obj) {
  if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

  var result = [];

  for (var prop in obj) {
    if (hasOwnProperty.call(obj, prop)) result.push(prop);
  }

  if (hasDontEnumBug) {
    for (var i=0; i < dontEnumsLength; i++) {
      if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
    }
  }
  return result;
}})()};

Recurso Firefox (Gecko) 4 (2.0) Chrome 5 Internet Explorer 9 Opera 12 Safari 5

Mais informações: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

Mas se você precisar apenas do primeiro, poderemos organizar uma solução mais curta, como:

var data = {"key1":"123","key2":"456"};
var first = {};
for(key in data){
    if(data.hasOwnProperty(key)){
        first.key = key;
        first.content =  data[key];
        break;
    }
}
console.log(first); // {key:"key",content:"123"}
Javier Cobos
fonte
2

Para obter o primeiro nome da chave no objeto, você pode usar:

var obj = { first: 'someVal' };
Object.keys(obj)[0]; //returns 'first'

Retorna uma string, para que você não possa acessar objetos aninhados, se houver, como:

var obj = { first: { someVal : { id : 1} }; Aqui com essa solução, você não pode acessar o id.

A melhor solução se você deseja obter o objeto real está usando o lodash, como:

obj[_.first(_.keys(obj))].id

Para retornar o valor da primeira chave (se você não souber exatamente o nome da primeira chave):

var obj = { first: 'someVal' };
obj[Object.keys(obj)[0]]; //returns 'someVal'

se você souber o nome da chave, use:

obj.first

ou

obj['first']
Diego Unanue
fonte
0

Se você precisar acessar "a primeira propriedade de um objeto", isso pode significar que há algo errado com sua lógica. A ordem das propriedades de um objeto não deve importar.

Flavius ​​Stef
fonte
Você está certo. Eu não preciso do primeiro, por si só, mas apenas de uma das propriedades foo para que eu possa trabalhar com ele. Eu só preciso de um e não tinha certeza se havia uma maneira apenas para agarrar o "primeiro" um sem usar for ... in.
atogle
0

Use uma matriz em vez de um objeto (colchetes).

var example = [ {/* stuff1 */}, { /* stuff2 */}, { /* stuff3 */}];
var fist = example[0];

Observe que você perde os identificadores 'foo'. Mas você pode adicionar uma propriedade name aos objetos contidos:

var example = [ 
  {name: 'foo1', /* stuff1 */},
  {name: 'foo2', /* stuff2 */},
  {name: 'foo3', /* stuff3 */}
];
var whatWasFirst = example[0].name;
steamer25
fonte
existem situações em que não podemos. Estamos assumindo que não podemos mudar o fato de que eles não estão em uma matriz
1mike12
1
Eu acho que é útil adiar um pouco o design para leitores que podem controlar seu esquema JSON. Essencialmente, estou estendendo a resposta de Flavius ​​Stef com alguns exemplos.
precisa saber é o seguinte
0

Alguma razão para não fazer isso?

> example.map(x => x.name);

(3) ["foo1", "foo2", "foo3"]
jtr13
fonte
8
Porque .map()só existe para iterables built-in
Kano
0

Você pode usar o Object.prototype.keysque retorna todas as chaves de um objeto na mesma ordem. Portanto, se você deseja o primeiro objeto, obtenha esse array e use o primeiro elemento como chave desejada.

const o = { "key1": "value1", "key2": "value2"};
const idx = 0; // add the index for which you want value
var key = Object.keys(o)[idx];
value = o[key]
console.log(key,value); // key2 value2
akash kumar
fonte
1
Ao responder a uma pergunta antiga, sua resposta seria muito mais útil para outros usuários do StackOverflow se você incluísse algum contexto para explicar como sua resposta ajuda, principalmente para uma pergunta que já tenha uma resposta aceita. Veja: Como escrevo uma boa resposta .
David Buck
0

também podemos fazer com esse método.

var example = {
  foo1: { /* stuff1 */},
  foo2: { /* stuff2 */},
  foo3: { /* stuff3 */}
}; 
Object.entries(example)[0][1];
Salil Sharma
fonte
0

Aqui está uma maneira mais limpa de obter a primeira chave:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

var object2 = {
    needThis: 'This is a value of the property',
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

let [first] = Object.keys(example)
let [firstProp] = Object.keys(object2)

console.log(first)
//Prop : needThis, Value: This is a value of the property
console.log(`Prop : ${firstProp}, Value: ${object2[firstProp]}`)

Ntiyiso Rikhotso
fonte
Mas por que a matriz ao redor [first]. O usuário não solicitou uma matriz como resposta. Por que fazer isso sobre o first = Object.keys(example)[0]que fará o mesmo sem precisar agrupar a resposta em uma matriz. Por que o seu é mais limpo, por favor?
Michael Durrant
Essa é uma tarefa de desestruturação developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Ntiyiso Rikhotso