For..In loops en JavaScript - pares de valores clave


414

Me preguntaba si hay una manera de hacer algo como un foreachbucle PHP en JavaScript. La funcionalidad que estoy buscando es algo como este fragmento de PHP:

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

Estaba mirando el for..inbucle JS , pero parece que no hay forma de especificar el as. Si hago esto con un bucle for 'normal' ( for(var i = 0; i < data.length; i++), ¿hay alguna manera de obtener los pares clave => valor?

Respuestas:


216

Si puede usar ES6 de forma nativa o con Babel (compilador js), puede hacer lo siguiente:

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

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

Lo que imprimirá esta salida:

a 1
b 2
c 3

El Object.entries()método devuelve una matriz de [key, value]pares de propiedades enumerables propias de un objeto dado , en el mismo orden que el proporcionado por un for...inbucle (la diferencia es que un bucle for-in también enumera propiedades en la cadena prototipo) .

¡Espero eso ayude! =)


1
Esto funciona perfecto, solo me pregunto: en comparación con "para la clave en el objeto y luego obtener valor por objeto [clave]", ¿cuál da un mejor rendimiento?
lsheng

1
En este caso específico, supongo que es más lento debido a la Object.entriesllamada. Sin embargo, no ejecuté ninguna prueba.
Francesco Casula

66
Esta es la mejor respuesta a la pregunta en cuestión, que se refería a tomar tanto la clave como el valor en el bucle for.
cipak

44
La respuesta aceptada debe actualizarse ya que esto realmente responde la pregunta, aunque no estaba disponible en el momento de la pregunta.
Marc Qualie

1
Es posible que desee verificar esta pregunta: stackoverflow.com/questions/47213651/… que parece indicar que se recomendaría una sintaxis de este tipo: Object.keys (myObject) .forEach (key => {...
Will59

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

hasOwnPropertyse utiliza para verificar si targetrealmente tiene esa propiedad, en lugar de haberla heredado de su prototipo. Un poco más simple sería:

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

Es sólo comprueba que kno es un método (como si targetes arrayque obtendrá una gran cantidad de métodos de alerta, por ejemplo indexOf, push, pop, etc.)


87
Otra forma de iterar solo sobre propiedades "propias" es Object.keys. Object.keys(target).forEach(function (key) { target[key]; });.
katspaugh

3
no va a funcionar si targetse crea usando Object.create(null), el código debe cambiarse target.hasOwnProperty(k)->Object.prototype.hasOwnProperty.call(target,k)
Azder

¿Por qué no utilizar las variables dadas en el ejemplo de la pregunta? Lo que aquí está k, targety property? Para mí, no javascripter esta área de indefinido :)
Gediminas

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

315

Nadie lo ha mencionado, Object.keysasí que lo mencionaré.

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

3
Nota: No es compatible con IE8 y versiones inferiores.
Edwin Stoteler

1
En este punto, debería estar utilizando una cuña ES5. Si vives en el agradable futuro de ES6, usa for of tc39wiki.calculist.org/es6/for-of
goatslacker el

17
Vale la pena señalar, que "No hay forma de detener o romper un ciclo forEach () que no sea lanzando una excepción"
rluks

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

No funciona en ES6 o no lo entiendo. Felix tiene una respuesta mejor y más legible a continuación: data.forEach (function (value, index) {console.log (index); // 0, 1, 2 ...});
gtamborero

115

para ... en trabajará para ti.

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

En JavaScript moderno también puedes hacer esto:

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

}

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

}

La sintaxis php es solo azúcar.


Esto también iterará en todas las propiedades heredadas. Para evitar esto, use .hasOwnProperty ().
LSerni

24

Supongo que sabe que esa ies la clave y que puede obtener el valor a través de data[i](y solo quiere un atajo para esto).

ECMAScript5 introdujo forEach [MDN] para las matrices (parece que tiene una matriz):

data.forEach(function(value, index) {

});

La documentación de MDN proporciona una cuña para los navegadores que no lo admiten.

Por supuesto, esto no funciona para los objetos, pero puede crear una función similar para ellos:

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

Desde que etiquetaste la pregunta con , jQuery proporciona $.each [docs] que recorre las estructuras de matriz y de objeto.


Eso es Array forEach, no un objeto forEach.

2
¿Entonces? Aparentemente, el OP está girando sobre una matriz.
Felix Kling

También Mozilla (Firefox, SpiderMonkey-C, Rhino & c) tiene una extensión no estándar que permite la for eachsintaxis. for each (let val in myObj) console.log(val);.
katspaugh

2
@katspaugh: Correcto, pero como es solo Mozilla, no parece ser muy útil.
Felix Kling

Muchas gracias por tu respuesta. Leeré la información que proporcionaste. Su suposición al comienzo de la respuesta era correcta, lo sabía, excepto que me dio tanta importancia con este proyecto que no puedo concentrarme y lo olvidé ... Gracias.
cabaret


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

En javascript, cada objeto tiene un par de pares clave-valor integrados que tienen metainformación. Cuando recorre todos los pares clave-valor de un objeto, también lo recorre. El uso de hasOwnProperty () los filtra.


2

ES6 proporcionará Map.prototype.forEach (devolución de llamada) que se puede usar de esta manera

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

2
¿Para qué sirve el parámetro myMap?
phil294

Un mapa no es un objeto. Son cosas completamente separadas.
Dakusan

2
La función forEach no contiene la 'clave' de la matriz, sino más bien el índice del elemento que está iterando actualmente.
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

55
Puede agregar alguna explicación con el código que publicó en lugar de publicar un código simple que podría no ser comprensible.
AaoIi

Object.entries saca una matriz de matrices basadas en los pares clave / valor del objeto original: [['a', 1],['b',2],['c',3]]. El forEachdeconstruye cada una de las matrices de clave / valor y establece las dos variables a keyy value, para ser utilizado como desea que la función - aquí en la salida console.log.
Mark Swardstrom el

1

Puede usar un bucle 'for in' para esto:

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


1

Si está usando Lodash , puede 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

En los últimos años desde que se hizo esta pregunta, Javascript ha agregado algunas características nuevas. Uno de ellos es el método Object.Entries .

Copiado directamente de MDN es el fragmento de código siguiente


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

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

-2

sí, puedes tener matrices asociativas también en 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 ... todo en javascript es un par clave-valor (por lo tanto, un objeto es de hecho una matriz asociativa de pares clave-valor ...)
Alex Pacurar

@AlexPacurar y la matriz asociativa tiene un orden. Un objeto no está ordenado.
esa

@Raynos puede que tenga razón ... será de gran ayuda explicar exactamente cómo se desordena un objeto ... dado el ejemplo anterior, uno esperaría que la 'i' en el bucle for sea [name, otherProperty, y finalmente fecha] ... entonces, ¿en qué situación se mezclará el orden de las propiedades de un objeto?
Alex Pacurar

@AlexPacurar el orden particular en que se repetirá sobre el objeto es específico del navegador. Algunos lo hacen por orden alfabético, algunos lo hacen orden de definición, etc
Raynos

3
@Raynos: ¿Se ordenan necesariamente las matrices asociativas? A menudo he visto el término usado de manera más general. Por ejemplo, en el artículo de Wikipedia de matriz asociativa .
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;
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.