Como obter todos os valores de propriedades de um Objeto JavaScript (sem conhecer as chaves)?


Respostas:


447

Usando um for..inloop simples :

for(var key in objects) {
    var value = objects[key];
}

90
Cuidado com as propriedades do objeto protótipo que está sendo herdado. Veja: hasOwnProperty ()
olive

102
Se você está lendo esta resposta, definitivamente deveria ler a outra
mgarciaisaia

18
Se você está lendo esta resposta e pode estar lidando com seqüências de caracteres, definitivamente deve dar um javascript na cara.

Se você leu a resposta acima e quer dar um soco no JavaScript, tente lodash
slugmandrew

Provavelmente, deve apontar que isso NÃO incluirá propriedades que tenham seu enumerablesinalizador definido como falso. Isso - entre outras coisas - significa que você não repetirá nenhum método de classe, mas que repetirá métodos criados de outras maneiras.
rica Remer

1012

Dependendo de quais navegadores você precisa oferecer suporte, isso pode ser feito de várias maneiras. A esmagadora maioria dos navegadores em estado selvagem oferece suporte ao ECMAScript 5 (ES5), mas esteja avisado de que muitos dos exemplos abaixo usam Object.keys, o que não está disponível no IE <9. Consulte a tabela de compatibilidade .

ECMAScript 3+

Se você precisar oferecer suporte a versões mais antigas do IE, esta é a opção para você:

for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
        var val = obj[key];
        // use val
    }
}

O aninhado ifgarante que você não enumere as propriedades na cadeia de protótipos do objeto (que é o comportamento que você quase certamente deseja). Você deve usar

Object.prototype.hasOwnProperty.call(obj, key) // ok

ao invés de

obj.hasOwnProperty(key) // bad

porque o ECMAScript 5+ permite criar objetos sem protótipo Object.create(null)e esses objetos não terão o hasOwnPropertymétodo O código malicioso também pode produzir objetos que substituem o hasOwnPropertymétodo.

ECMAScript 5+

Você pode usar esses métodos em qualquer navegador que suporte o ECMAScript 5 e superior. Eles obtêm valores de um objeto e evitam enumerar a cadeia de protótipos. Onde objestá o seu objeto:

var keys = Object.keys(obj);

for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]];
    // use val
}

Se você quer algo um pouco mais compacto ou deseja ter cuidado com funções em loops, então Array.prototype.forEaché seu amigo:

Object.keys(obj).forEach(function (key) {
    var val = obj[key];
    // use val
});

O próximo método cria uma matriz que contém os valores de um objeto. Isso é conveniente para fazer o loop.

var vals = Object.keys(obj).map(function (key) {
    return obj[key];
});

// use vals array

Se você deseja tornar os usuários Object.keysseguros contra null(como for-inestão), pode fazê-lo Object.keys(obj || {})....

Object.keysretorna propriedades enumeráveis . Para iterar sobre objetos simples, isso geralmente é suficiente. Se você tiver algo com propriedades não enumeráveis ​​com as quais precisa trabalhar, poderá usar Object.getOwnPropertyNamesno lugar de Object.keys.

ECMAScript 2015+ (AKA ES6)

As matrizes são mais fáceis de iterar com o ECMAScript 2015. Você pode usar isso para sua vantagem ao trabalhar com valores um por um em um loop:

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}

Usando as funções de seta de gordura do ECMAScript 2015, o mapeamento do objeto para uma matriz de valores se torna uma linha:

const vals = Object.keys(obj).map(key => obj[key]);

// use vals array

O ECMAScript 2015 apresenta Symbol, instâncias das quais podem ser usadas como nomes de propriedades. Para obter os símbolos de um objeto para enumerar, use Object.getOwnPropertySymbols(essa função é a razão pela qual Symbol não pode ser usada para criar propriedades particulares). A nova ReflectAPI do ECMAScript 2015 fornece Reflect.ownKeys, que retorna uma lista de nomes de propriedades (incluindo nomes não enumeráveis) e símbolos.

Compreensões de matriz (não tente usar)

As compreensões da matriz foram removidas do ECMAScript 6 antes da publicação. Antes da remoção, uma solução seria semelhante a:

const vals = [for (key of Object.keys(obj)) obj[key]];

// use vals array

ECMAScript 2017+

O ECMAScript 2016 adiciona recursos que não afetam esse assunto. A especificação ECMAScript 2017 adiciona Object.valuese Object.entries. Ambas as matrizes de retorno (o que será surpreendente para alguns, dada a analogia com Array.entries). Object.valuespode ser usado como está ou com um for-ofloop.

const values = Object.values(obj);

// use values array or:

for (const val of Object.values(obj)) {
    // use val
}

Se você deseja usar tanto a chave quanto o valor, então Object.entriesé para você. Produz uma matriz cheia de [key, value]pares. Você pode usar isso como está, ou (observe também a atribuição de desestruturação do ECMAScript 2015) em um for-ofloop:

for (const [key, val] of Object.entries(obj)) {
    // use key and val
}

Object.values calço

Finalmente, como observado nos comentários e por teh_senaus em outra resposta, pode valer a pena usar um deles como calço. Não se preocupe, o seguinte não altera o protótipo, apenas adiciona um método a Object(que é muito menos perigoso). Usando funções de seta gorda, isso também pode ser feito em uma linha:

Object.values = obj => Object.keys(obj).map(key => obj[key]);

que agora você pode usar como

// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });

Se você deseja evitar o desgaste quando um nativo Object.valuesexiste, você pode:

Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));

Finalmente...

Esteja ciente dos navegadores / versões que você precisa oferecer suporte. Os itens acima estão corretos onde os métodos ou recursos de linguagem são implementados. Por exemplo, o suporte ao ECMAScript 2015 foi desativado por padrão na V8 até recentemente, que alimentava navegadores como o Chrome. Os recursos do ECMAScript 2015 devem ser evitados até que os navegadores que você pretende oferecer suporte implementem os recursos necessários. Se você usar o babel para compilar seu código no ECMAScript 5, terá acesso a todos os recursos nesta resposta.


9
Essa deve ser a resposta aceita (ou pelo menos mais votada), pois a resposta aceita está incompleta (@olive aponta isso).
0xc0de 26/09/2013

É uma pena que, de todos os chamados truques, ainda precisamos mencionar objduas vezes. Eu acho que criar uma função auxiliar é inevitável? Algo como valores (obj).
precisa

Qualquer um desses métodos pode ser usado como calço. Por exemplo:Object.values = obj => Object.keys(obj).map(key => obj[key]);
qubyte 24/11/2013

1
As soluções ECMA 5 devem funcionar em todos os navegadores modernos. O ECMA 6 ainda não foi finalizado e o suporte é preliminar em todos os navegadores. No Chrome, o ECMA 6 é parcialmente implementado, mas desativado. No Firefox, o suporte é melhor, mas a compreensão da matriz está errada (como mencionado). Eu pensei que meu uso do tempo futuro implicaria isso. @JacekLampart, qual solução deu o erro?
qubyte

2
Não consigo imaginar por que precisamos esperar pelo ES2017 para obter um método Object.values ​​().
23416 Herbertusz

31

Aqui está uma função reutilizável para obter os valores em uma matriz. Também leva em consideração os protótipos.

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.push(obj[key]);
        }
    }
    return vals;
}

15
Modificar Objectnão é um grande problema ( Object.keysé um calço comum), você provavelmente está pensando em modificar o protótipo de Objeto.
Sandstrom

Por que você precisaria testar hasOwnProperty()? Como a chave seria iterada no loop desse objeto que não possui a propriedade?
1252748

4
Pesquise no Google, é importante. Pode ter propriedades de sua cadeia de protótipos.
19414 Joe

28

Se você tiver acesso ao Underscore.js, poderá usar a _.valuesfunção assim:

_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]

@MathieuAmiot - cuidados para explicar?
Paden

O lodash é um substituto compatível com a API para o sublinhado, um (muito) mais rápido.
Mathieu Amiot

@Paden, aqui está uma pergunta relacionada ao SO: stackoverflow.com/questions/13789618/…
jichi

2
lodash é desnecessário para isso e vai inchar sua base de código
dman

14

Se você realmente quer uma matriz de valores, acho isso mais limpo do que construir uma matriz com um loop for ... in.

ECMA 5.1+

function values(o) { return Object.keys(o).map(function(k){return o[k]}) }

Vale a pena notar que, na maioria dos casos, você realmente não precisa de uma matriz de valores, será mais rápido fazer isso:

for(var k in o) something(o[k]);

Isso itera sobre as chaves do Objeto o. Em cada iteração, k é definido como uma chave de o.


9

ES5 Object.keys

var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]

3
Por que isso foi rebaixado? Eu diria que esta é uma das soluções mais limpas.
Sebastian Hojas 16/05

Eu não sei, por que isso é votado? Essa é a solução mais fácil e pura em js sem usar nenhuma biblioteca ou qualquer outro utilitário.
sanjeev shetty

5

Você pode percorrer as teclas:

foo = {one:1, two:2, three:3};
for (key in foo){
    console.log("foo["+ key +"]="+ foo[key]);
}

irá produzir:

foo[one]=1
foo[two]=2
foo[three]=3

2
Você também precisa verificar `hasOwnProperty () 'se quiser evitar atributos herdados.
0xc0de 26/09/2013

3

Para as pessoas que se adaptaram cedo na era CofeeScript, aqui está outro equivalente.

val for key,val of objects

O que pode ser melhor do que isso, pois objectspode ser reduzido para ser digitado novamente e diminuiu a legibilidade.

objects[key] for key of objects

3

use um polyfill como:

if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}

então use

Object.values(my_object)

3) lucro!



2

Aparentemente - como eu aprendi recentemente - esta é a maneira mais rápida de fazer isso:

var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
    // do whatever in here
    var obj = objs[objKeys[i]];
}

você pode colocar um codepen ou jsfiddle de um exemplo disso? obrigado.
precisa

2

A pergunta não especifica se também deseja propriedades herdadas e não enumeráveis.

uma pergunta para obter tudo, propriedades herdadas e propriedades não enumeráveis ​​também , que o Google não consegue encontrar facilmente.

Minha solução para isso é:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

E então itere sobre eles, basta usar um loop for-of:


1

Use Object.values():, passamos um objeto como argumento e recebemos uma matriz dos valores como valor de retorno.

Isso retorna uma matriz de valores de propriedades enumeráveis ​​próprias de um determinado objeto. Você obterá os mesmos valores usando o for inloop, mas sem as propriedades no Prototype. Este exemplo provavelmente tornará as coisas mais claras:

function person (name) {
  this.name = name;
}

person.prototype.age = 5;

let dude = new person('dude');

for(let prop in dude) {
  console.log(dude[prop]);     // for in still shows age because this is on the prototype
}                              // we can use hasOwnProperty but this is not very elegant

// ES6 + 
console.log(Object.values(dude));
// very concise and we don't show props on prototype


1
const object1 = {
  a: 'somestring',
  b: 42
};

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}

// expected output:
// "a: somestring"
// "b: 42"
// order is not guaranteed

0

Aqui está uma função semelhante ao array_values ​​() do PHP

function array_values(input) {
  var output = [], key = '';
  for ( key in input ) { output[output.length] = input[key]; }
  return output;
}

Veja como obter os valores do objeto se você estiver usando o ES6 ou superior:

Array.from(values(obj));

Por alguma razão, values ​​() está funcionando no Chrome e Firefox, mas não no iojs / node.
Jaggedsoft

0

Compatível com o ES7, mesmo alguns navegadores ainda não o suportam

Desde então, Object.values(<object>)será incorporado no ES7 e

Até esperar todos os navegadores para suportá-lo, você pode envolvê-lo em uma função

Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])

Então :

Object.vals({lastname:'T',firstname:'A'})
 // ['T','A']

Depois que os navegadores se tornarem compatíveis com o ES7, você não precisará alterar nada no seu código.


0

Percebo que estou um pouco atrasado, mas aqui está um calço para o novo Object.valuesmétodo do firefox 47

Object.prototype.values = Object.prototype.values || function(obj) {
  return this.keys(obj).map(function(key){
    return obj[key];
  });
};

0

Object.entries faz isso da melhor maneira.

  var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
 
   Object.entries(dataObject).map(itemArray => { 
     console.log("key=", itemArray[0], "value=", itemArray[1])
  })


0

const myObj = { a:1, b:2, c:3 }

Obtenha todos os valores:

  • o caminho mais curto:

    • const myValues = Object.values(myObj)
  • const myValues = Object.keys(myObj).map(key => myObj[key])


-1
var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }

-5

no uso do ECMAScript5

 keys = Object.keys(object);

Caso contrário, se o seu navegador não o suportar, use o conhecido for..in loop

for (key in object) {
    // your code here
}

17
A pergunta estava pedindo os valores, não as chaves.
22412 zachelrath

@zachelrath Você está certo. - Mas esse script é útil se você deseja obter os valores, porque quando você conhece as chaves, pode usar object[key]para obter os valores em um loop.
Fridojet

2
@fridojet Mas isso pode ser feito com for..in(e hasOwnProperty) para que realmente não ganhe nada. Desejo que o ECMAScript 5th seja definido Object.pairs(e Object.itemspara [[key, value], ..]), mas, infelizmente, isso não acontece.
User2246674

-8

Agora eu uso o Dojo Toolkit porque navegadores mais antigos não suportam Object.values.

require(['dojox/lang/functional/object'], function(Object) {
    var obj = { key1: '1', key2: '2', key3: '3' };
    var values = Object.values(obj);
    console.log(values);
});

Resultado :

['1', '2', '3']

5
A rigor, a matriz não está correta. Você tem uma matriz de seqüências de caracteres em vez de uma matriz de números.
qubyte

-10

usar

console.log(variable)

e se você estiver usando o Google Chrome, abra o Console usando Ctrl + Shift + j

Saltar >> Console

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.