Loops For..In em JavaScript - pares de valores-chave


414

Eu queria saber se existe uma maneira de fazer algo como um foreachloop PHP em JavaScript. A funcionalidade que estou procurando é algo como este trecho de código PHP:

foreach($data as $key => $value) { }

Eu estava olhando para o for..inloop JS , mas parece não haver maneira de especificar o as. Se eu fizer isso com um loop for 'normal' ( for(var i = 0; i < data.length; i++), existe uma maneira de pegar os pares chave => valor?

Respostas:


216

Se você pode usar o ES6 nativamente ou com o Babel (compilador js), poderá fazer o seguinte:

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

for (const [key, value] of Object.entries(test)) {
  console.log(key, value);
}

O que imprimirá esta saída:

a 1
b 2
c 3

O Object.entries()método retorna uma matriz dos [key, value]pares de propriedades enumeráveis ​​de um determinado objeto , na mesma ordem que a fornecida por um for...inloop (a diferença é que um loop for-in também enumera propriedades na cadeia de protótipos) .

Espero que ajude! =)


1
Isso funciona perfeito, apenas imaginando - comparado a "para digitar objeto e depois obter valor por objeto [chave]", qual deles oferece melhor desempenho?
Lsheng

1
Nesse caso específico, eu diria que é mais lento por causa da Object.entrieschamada. Eu não fiz nenhum teste.
Francesco Casula

6
esta é a melhor resposta para a pergunta em questão, que perguntou sobre pegar a chave e o valor no loop for.
Cipak

4
A resposta aceita deve ser atualizada, pois ela realmente responde à pergunta, embora não estivesse disponível no momento da pergunta.
Marc Qualie

1
Convém verificar esta pergunta: stackoverflow.com/questions/47213651/…, que parece indicar que uma sintaxe desse tipo seria recomendada: Object.keys (myObject) .forEach (key => {...
Will59

519
for (var k in target){
    if (target.hasOwnProperty(k)) {
         alert("Key is " + k + ", value is " + target[k]);
    }
}

hasOwnPropertyé usado para verificar se você targetrealmente possui essa propriedade, em vez de herdá-la de seu protótipo. Um pouco mais simples seria:

for (var k in target){
    if (typeof target[k] !== 'function') {
         alert("Key is " + k + ", value is" + target[k]);
    }
}

É apenas cheques que knão é um método (como se targeté arrayque você vai ter um monte de métodos alertado, por exemplo indexOf, push, pop, etc.)


87
Outra maneira de iterar apenas sobre propriedades "próprias" é Object.keys. Object.keys(target).forEach(function (key) { target[key]; });.
precisa saber é o seguinte

3
não vai funcionar se targetfor criado usando Object.create(null), o código deve ser alterado target.hasOwnProperty(k)->Object.prototype.hasOwnProperty.call(target,k)
Azder

por que não usar variáveis ​​dadas no exemplo em questão? O que aqui está k, targete property? Para mim, não javascripter esta área de indefinido :)
Gediminas

2
Object.keys (target) .forEach ((key) => {target [key];}); para Angular
askilondz

315

Ninguém mencionou, Object.keysentão eu vou mencionar.

Object.keys(obj).forEach(function (key) {
   // do something with obj[key]
});

3
Nota: Não suportado pelo IE8 e abaixo.
Edwin Stoteler

1
Neste ponto, você deve estar usando um calço ES5. Se você está vivendo no bom futuro do ES6, use for of tc39wiki.calculist.org/es6/for-of
goatslacker

17
É interessante notar, que "Não há nenhuma maneira de parar ou quebrar um loop foreach () que não seja lançando uma exceção"
rluks

Object.keys (obj) .forEach ((key) => {}); para Angular
askilondz

Não funciona no ES6 ou não o entendo. Felix tem uma resposta melhor e mais legível abaixo: data.forEach (function (value, index) {console.log (index); // 0, 1, 2 ...});
Gtamborero 30/01/19

115

pois ... funcionará para você.

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

No JavaScript moderno, você também pode fazer isso:

for ( const [key,value] of Object.entries( obj ) ) {

}

64
var obj = {...};
for (var key in obj) {
    var value = obj[key];

}

A sintaxe php é apenas açúcar.


Isso também irá iterar em todas as propriedades herdadas. Para evitar isso, use .hasOwnProperty ().
precisa saber é o seguinte

24

Suponho que você saiba que essa ié a chave e que você pode obter o valor via data[i](e apenas deseja um atalho para isso).

O ECMAScript5 introduziu forEach [MDN] para matrizes (parece que você tem uma matriz):

data.forEach(function(value, index) {

});

A documentação do MDN fornece uma correção para os navegadores que não suportam.

Claro que isso não funciona para objetos, mas você pode criar uma função semelhante para eles:

function forEach(object, callback) {
    for(var prop in object) {
        if(object.hasOwnProperty(prop)) {
            callback(prop, object[prop]);
        }
    }
}

Desde que você marcou a pergunta com , o jQuery fornece $.each [docs] que circula as estruturas de array e de objeto.


Isso é matriz forEach, não objeto forEach.

2
Assim? Aparentemente, o OP está circulando sobre uma matriz.
precisa saber é o seguinte

Além disso, o Mozilla (Firefox, SpiderMonkey-C, Rhino etc.) possui uma extensão não padrão que permite a for eachsintaxe. for each (let val in myObj) console.log(val);.
precisa saber é o seguinte

2
@katspaugh: Certo, mas como é apenas o Mozilla, não parece ser muito útil.
precisa

Muito obrigado pela sua resposta. Vou ler as informações que você forneceu. Sua suposição no início da resposta estava correta, eu sabia disso, exceto que eu me envolvi tanto com esse projeto que não consigo me concentrar e esqueci. Obrigado.
Cabaret


9
for (var key in myMap) {
    if (myMap.hasOwnProperty(key)) {
        console.log("key =" + key);
        console.log("value =" + myMap[key]);
    }
}

Em javascript, todo objeto possui vários pares de valores-chave incorporados que possuem meta-informações. Quando você percorre todos os pares de valores-chave de um objeto, você também os percorre. O uso de hasOwnProperty () os filtra.


2

O ES6 fornecerá Map.prototype.forEach (callback), que pode ser usado assim

myMap.forEach(function(value, key, myMap) {
                        // Do something
                    });

2
qual é o parâmetro myMappara?
phil294

Um mapa não é um objeto. São coisas completamente separadas.
Dakusan

2
A função forEach não contém a 'chave' da matriz, mas mais o índice do elemento que você está iterando no momento.
Francis Malloch

2
let test = {a: 1, b: 2, c: 3};
Object.entries(test).forEach(([key, value]) => console.log(key, value))

// a 1
// b 2
// c 3

5
Você pode adicionar alguma explicação com o código publicado em vez de publicar um código simples que pode não ser compreensível.
AaoIi 17/08/18

Object.entries puxa para fora uma matriz de matrizes com base nos pares de chave / valor do objecto original: [['a', 1],['b',2],['c',3]]. A forEachdesconstrói cada uma das matrizes de chave / valor e define as duas variáveis ​​como keye value, para serem usadas como você deseja que a função in - seja exibida aqui console.log.
Mark Swardstrom

1

Você pode usar um loop 'for in' para isso:

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


1

Se você estiver usando o Lodash , poderá usar_.forEach

_.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
  console.log(key + ": " + value);
});
// => Logs 'a: 1' then 'b: 2' (iteration order is not guaranteed).

1

Nos últimos anos desde que essa pergunta foi feita, o Javascript adicionou alguns novos recursos. Um deles é o método Object.Entries .

Copiado diretamente do MDN é o seguinte trecho de código


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

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

-2

sim, você pode ter matrizes associativas também em javascript:

var obj = 
{
    name:'some name',
    otherProperty:'prop value',
    date: new Date()
};
for(i in obj)
{
    var propVal = obj[i]; // i is the key, and obj[i] is the value ...
}

@PaulPRO ... tudo em javascript é um par chave-valor (assim, um objeto é na verdade uma matriz associativa de pares chave-valor ...)
Alex Pacurar

O @AlexPacurar e o array associado têm um pedido. Um objeto não está ordenado. Isso é uma grande diferença
Raynos

@ Raynos, você pode estar certo ... será uma grande ajuda explicar exatamente como um objeto é desordenado ... dado o exemplo acima, seria de esperar que o 'i' no loop for fosse [name, otherProperty, e finalmente date] ... então em qual situação a ordem das propriedades de um objeto será misturada?
Alex Pacurar

@AlexPacurar, a ordem específica em que ele fará um loop sobre o objeto é específica do navegador. Alguns fazem isso em ordem alfabética, alguns fazem-ordem de definição, etc
Raynos

3
@ Raynos: As matrizes associativas são necessariamente ordenadas? Eu sempre vi o termo usado de maneira mais geral. Por exemplo, no artigo da Wikipedia sobre matriz associativa .
Jeremy Banks

-8
var global = (function() {
   return this;
})();

// Pair object, similar to Python

function Pair(key, value) {
    this.key = key;
    this.value = value;

    this.toString = function() {
       return "(" + key + ", " + value + ")";
    };
}

/**
 * as function
 * @param {String} dataName A String holding the name of your pairs list.
 * @return {Array:Pair} The data list filled
 *    with all pair objects.
 */
Object.prototype.as = function(dataName) {
    var value, key, data;
    global[dataName] = data = [];

    for (key in this) {
       if (this.hasOwnProperty(key)) {
          value = this[key];

          (function() {
             var k = key,
                 v = value;

            data.push(new Pair(k, v));
          })();
       }
    }

    return data;
};

var d = {
   'one': 1,
   'two': 2
};

// Loop on your (key, list) pairs in this way
for (var i = 0, max = d.as("data").length; i < max; i += 1) {
   key = data[i].key;
   value = data[i].value;

   console.log("key: " + key + ", value: " + value);
}

// delete data when u've finished with it.
delete data;
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.