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.

Há 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.