Obter matriz de chaves do objeto

371

Gostaria de obter as chaves de um objeto JavaScript como uma matriz, em jQuery ou em JavaScript puro.

Existe uma maneira menos detalhada do que isso?

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}
Richard
fonte
4
Além de adicionar if(foo.hasOwnProperty(key)), é o que eu faria. Ou use $.map.
Rocket Hazmat
10
Mas para uma linha Pythonic, no entanto ...
Richard
uma velha questão, portanto, não vale a pena uma resposta completa, mas para aqueles que querem violino ... jsfiddle.net/LR5D9/3 ofertas esta solução com a emissão das declarações de protótipo bagunçar for var in xlaços
não sincronizadas

Respostas:

618

Use Object.keys:

var foo = {
  'alpha': 'puffin',
  'beta': 'beagle'
};

var keys = Object.keys(foo);
console.log(keys) // ['alpha', 'beta'] 
// (or maybe some other order, keys are unordered).

Esse é um recurso do ES5. Isso significa que ele funciona em todos os navegadores modernos, mas não nos navegadores herdados .

O ES5-shim possui uma implementação que Object.keysvocê pode roubar

Raynos
fonte
5
Nota: Isso funciona apenas em navegadores modernos (com isso, quero dizer, não no IE <9).
Rocket Hazmat
2
E os navegadores móveis?
Marwen Trabelsi
11
@SmartyTwiti: Não tenho certeza. Eu diria que sim, como Chrome ou Firefox.
Foguete Hazmat
A MDN também possui o Polyfill acima mencionado, mas observa erros no IE7 e talvez 8, e depois se refere a um Polyfill muito mais curto aqui: tokenposts.blogspot.com.au/2012/04//
Campbeln
Então, como alguém fez isso antes do ES5?
Andrew S
59

Você pode usar o jQuery $.map.

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});
Foguete Hazmat
fonte
Ou each, se você estiver fazendo algo com eles. $.each(foo, function(index, value){/* do something with index */});
Chris
33

Obviamente, Object.keys()é a melhor maneira de obter as chaves de um objeto. Se ele não estiver disponível no seu ambiente, ele pode ser banido trivialmente usando código como no seu exemplo (exceto que você precisa levar em consideração que seu loop iterará sobre todas as propriedades da cadeia de protótipos, diferentemente Object.keys()do comportamento).

No entanto, seu código de exemplo ...

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}

jsFiddle .

... pode ser modificado. Você pode fazer a atribuição diretamente na parte variável .

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i++] in foo) {}

jsFiddle .

Obviamente, esse comportamento é diferente do que Object.keys()realmente faz ( jsFiddle ). Você pode simplesmente usar o calço na documentação do MDN .

alex
fonte
8
Eu gostei disso var keys = [], i = 0; for (keys[i++] in foo) {}+1
Jashwant 01/02
Ouvi dizer que "for in" não garante ordem, você sabe se Object.keys faz?
Chris Stephens
@ChrisStephens Nem garante a ordem, mesmo que as chaves acabem em uma matriz ordenada.
13133 alex
2
todas essas soluções precisam de um hasOwnProperty()cheque, com certeza?
não sincronizado
11
@TIMINeutron Não há nenhuma razão pela qual não deveria :)
alex
7

Eu não sei nada menos detalhado, mas fui inspirado a coagir o seguinte em uma linha pelo pedido de uma linha, mas não sei o quão Pythonic é;)

var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
Dexygen
fonte
3
Talvez que deve ser var enumerableKeysOnThePrototypeChain;)
alex
11
Talvez sejamos suficientemente inteligente para saber que não precisa se preocupar com hasOwnProperty se o objeto é criado inteiramente sob nosso alcance em vez de ser importado de outro lugar
Dexygen
não tão pítônico quanto a segunda resposta de @ alex ( for (keys[i++] in foo) {}), porque você ainda está executando Array.push()(para não mencionar a declaração de uma função inteira). Uma implementação python deve confiar tanto na compreensão implícita quanto possível e, na sua falta, usando uma expressão lambda.
cowbert
4

Caso você esteja aqui procurando algo para listar as chaves de um objeto aninhado de profundidade n como uma matriz plana:

const getObjectKeys = (obj, prefix = '') => {
  return Object.entries(obj).reduce((collector, [key, val]) => {
    const newKeys = [ ...collector, prefix ? `${prefix}.${key}` : key ]
    if (Object.prototype.toString.call(val) === '[object Object]') {
      const newPrefix = prefix ? `${prefix}.${key}` : key
      const otherKeys = getObjectKeys(val, newPrefix)
      return [ ...newKeys, ...otherKeys ]
    }
    return newKeys
  }, [])
}

console.log(getObjectKeys({a: 1, b: 2, c: { d: 3, e: { f: 4 }}}))

Cody Moniz
fonte
1

Sumário

Para obter todas as chaves de um objeto, você pode usar Object.keys(). Object.keys()pega um objeto como argumento e retorna uma matriz de todas as chaves.

Exemplo:

const object = {
  a: 'string1',
  b: 42,
  c: 34
};

const keys = Object.keys(object)

console.log(keys);

console.log(keys.length) // we can easily access the total amount of properties the object has

No exemplo acima, armazenamos uma matriz de chaves nas chaves const. Em seguida, podemos acessar facilmente a quantidade de propriedades no objeto, verificando o comprimento da matriz de chaves.

Obtendo os valores com: Object.values()

A função complementar de Object.keys()é Object.values(). Essa função pega um objeto como argumento e retorna uma matriz de valores. Por exemplo:

const object = {
  a: 'random',
  b: 22,
  c: true
};


console.log(Object.values(object));

Willem van der Veen
fonte
1

Se você decidir usar o Underscore.js, é melhor fazer

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
mohammad javad ahmadi
fonte