542

I was wondering if there's a way to do something like a PHP foreach loop in JavaScript. The functionality I'm looking for is something like this PHP Snippet:

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

I was looking at the JS for..in loop, but there seems to be no way to specify the as. If I do this with a 'normal' for loop (for(var i = 0; i < data.length; i++), is there a way to grab the key => value pairs?

TTT
  • 1,848
  • 2
  • 30
  • 60
Joris Ooms
  • 11,880
  • 17
  • 67
  • 124

19 Answers19

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

hasOwnProperty is used to check if your target really has that property, rather than having inherited it from its prototype. A bit simpler would be:

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

It just checks that k is not a method (as if target is array you'll get a lot of methods alerted, e.g. indexOf, push, pop,etc.)

Michael Levy
  • 13,097
  • 15
  • 66
  • 100
J0HN
  • 26,063
  • 5
  • 54
  • 85
  • 91
    Another way to iterate only over "own" properties is `Object.keys`. `Object.keys(target).forEach(function (key) { target[key]; });`. – katspaugh Aug 30 '11 at 10:50
  • 5
    not going to work if `target` is created using `Object.create(null)`, code should be changed `target.hasOwnProperty(k)` -> `Object.prototype.hasOwnProperty.call(target,k)` – Azder Sep 30 '15 at 09:49
  • 1
    why not to use variables given in question example? What here is `k`, `target` and `property`? For me, non-javascripter this area of undefined :) – Gediminas Šukys Mar 30 '17 at 13:24
  • 2
    Object.keys(target).forEach((key) => { target[key]; }); for Angular – askilondz Aug 18 '17 at 17:30
  • I would say that almost every time you see `obj.hasOwnProperty(k)` it should be rewritten as `Object.prototype.hasOwnProperty.call(obj, k)`. If you don't know whether or not an object has an own property `k`, then you probably also don't know *for sure* whether it has an own property named `"hasOwnProperty"`; and if it does, you don't want that one, you want the one from `Object.prototype`. So IMO making `hasOwnProperty` a method at all was a design flaw in the language; nobody ever wants its behaviour to be overridden in practice. – kaya3 Jan 17 '22 at 01:56
437

If you can use ES6 natively or with Babel (js compiler) then you could do the following:

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

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

Which will print out this output:

a 1
b 2
c 3

The Object.entries() method returns an array of a given object's own enumerable property [key, value] pairs, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).

Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73
Francesco Casula
  • 26,184
  • 15
  • 132
  • 131
  • 1
    This works perfect, just wondering - compared to "for key in object and then get value by object[key]", which one gives better performance? – lsheng Jul 09 '17 at 05:44
  • 2
    In this specific case I would assume it's slower because of the `Object.entries` call. I didn't run any tests though. – Francesco Casula Jul 09 '17 at 06:44
  • 7
    this is the best answer to the question at hand, which asked about grabbing both key and value in the for loop. – cipak Jan 13 '18 at 18:12
  • 4
    The accepted answer should be updated since this actually answers the question, although it wasn't available at time of the question. – Marc Qualie May 13 '18 at 20:44
  • 2
    You might want to check this question: https://stackoverflow.com/questions/47213651/caught-between-two-no-restricted-syntax-violations which seems to indicate that a syntax of this type would be recommended: Object.keys(myObject).forEach(key => {... – Will59 Dec 21 '19 at 00:09
  • carefull when using this with file object – Chukwuemeka Maduekwe Nov 09 '20 at 22:42
  • Is there an IE-friendly version? – Delmontee Jan 22 '21 at 10:36
  • Just answered my own question...It doesn't work in IE. Use the answer directly below for a solution to this. – Delmontee Jan 22 '21 at 10:42
344

No one has mentioned Object.keys so I'll mention it.

Object.keys(obj).forEach(function (key) {
   // do something with obj[key]
});
Afshin Moazami
  • 2,092
  • 5
  • 33
  • 55
goatslacker
  • 10,032
  • 2
  • 15
  • 15
  • 3
    Note: Not supported by IE8 and below. – Edwin Stoteler Dec 08 '14 at 07:57
  • 2
    At this point you should be using an ES5 shim. If you're living in the nice ES6 future use `for of` http://tc39wiki.calculist.org/es6/for-of/ – goatslacker Dec 11 '14 at 09:15
  • 23
    It is worth noting, that "There is no way to stop or break a forEach() loop other than by throwing an exception" – rluks Jan 03 '16 at 16:43
  • Object.keys(obj).forEach((key) => { }); for Angular – askilondz Aug 18 '17 at 17:29
  • It doesn't work on ES6 or I don't understand it. Felix has a better and more readable answer below: data.forEach(function(value, index) { console.log(index); // 0 , 1, 2... }); – gtamborero Jan 30 '19 at 22:15
  • I like this approach because it enables function chaining – Memet Olsen Aug 09 '19 at 10:10
  • this isn't ideal for function chaining because it does not return a result, but instead produces a side effect--usually function chaining is used in a functional way. If you want to act on an array in a functional chaining style, better to use 'map' or 'reduce', etc. – Kyle Baker Jan 25 '21 at 18:48
  • to those worried about not being able to exit the loop--while that is true, if you need to stop it mid-run, you should probably be used a different method, like Array's 'some()' or 'every()' or 'find()'. – Kyle Baker Jan 25 '21 at 18:49
145

for...in will work for you.

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

In modern JavaScript you can also do this:

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

}
Paul
  • 139,544
  • 27
  • 275
  • 264
72
var obj = {...};
for (var key in obj) {
    var value = obj[key];

}

The php syntax is just sugar.

JD.
  • 3,005
  • 2
  • 26
  • 37
Zirak
  • 38,920
  • 13
  • 81
  • 92
28

I assume you know that i is the key and that you can get the value via data[i] (and just want a shortcut for this).

ECMAScript5 introduced forEach [MDN] for arrays (it seems you have an array):

data.forEach(function(value, index) {

});

The MDN documentation provides a shim for browsers not supporting it.

Of course this does not work for objects, but you can create a similar function for them:

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

Since you tagged the question with , jQuery provides $.each [docs] which loops over both, array and object structures.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • That's Array `forEach`, not object `forEach`. –  Aug 30 '11 at 10:38
  • 2
    So? Apparently the OP is looping over an array. – Felix Kling Aug 30 '11 at 10:41
  • Also Mozilla (Firefox, SpiderMonkey-C, Rhino &c) has an non-standard extension that allows `for each` syntax. `for each (let val in myObj) console.log(val);`. – katspaugh Aug 30 '11 at 10:43
  • 2
    @katspaugh: Right, but as it is Mozilla only, it does not seem to be very useful. – Felix Kling Aug 30 '11 at 10:45
  • Thanks a lot for your answer. I'll read over the information you provided. Your assumption at the start of the answer was right, I knew that, except I got so much on my head with this project that I can't focus and forgot about it.. Thank you. – Joris Ooms Aug 30 '11 at 10:47
  • Ugh. `Object.keys(obj).forEach`. Everyone knows you should iterate over the keys. – Raynos Aug 30 '11 at 10:48
  • @Raynos: Not every ES5 feature completely got to me ;) It still would not give you the corresponding value. – Felix Kling Aug 30 '11 at 10:49
12

There are three options to deal with keys and values of an object:

  1. Select values:

    Object.values(obj).forEach(value => ...);
    
  2. Select keys:

    Object.keys(obj).forEach(key => ...);
    
  3. Select keys and values:

    Object.entries(obj).forEach(([key, value]) => ...);
    
Tonatio
  • 4,026
  • 35
  • 24
10
for (var key in myMap) {
    if (myMap.hasOwnProperty(key)) {
        console.log("key =" + key);
        console.log("value =" + myMap[key]);
    }
}

In javascript, every object has a bunch of built-in key-value pairs that have meta-information. When you loop through all the key-value pairs for an object you're looping through them too. The use of hasOwnProperty() filters these out.

Siddhu
  • 389
  • 1
  • 4
  • 8
9

You can use the for..in for that.

for (var key in data)
{
    var value = data[key];
}
Christoph Winkler
  • 6,278
  • 1
  • 18
  • 18
6
let test = {a: 1, b: 2, c: 3};
Object.entries(test).forEach(([key, value]) => console.log(key, value))

// a 1
// b 2
// c 3
ife
  • 1,231
  • 13
  • 13
  • 6
    You may add some explanation with the code you posted instead of posting a plain code which might be not understandable. – AaoIi Aug 17 '18 at 12:30
  • 1
    Object.entries pulls out an array of arrays based on the key/value pairs of the original object: `[['a', 1],['b',2],['c',3]]`. The `forEach` deconstructs each of the key/value arrays and sets the two variables to `key` and `value`, to be used as you want the in function - here output in `console.log`. – Mark Swardstrom Nov 18 '19 at 22:16
5

In the last few year since this question was made, Javascript has added a few new features. One of them is the Object.Entries method.

Copied directly from MDN is the follow code snippet


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

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}
David
  • 17,673
  • 10
  • 68
  • 97
2

ES6 will provide Map.prototype.forEach(callback) which can be used like this

myMap.forEach(function(value, key, myMap) {
                        // Do something
                    });
Stephen Murby
  • 1,407
  • 3
  • 17
  • 37
1

If you are using Lodash, you can use _.forEach

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

You can use a 'for in' loop for this:

for (var key in bar) {
     var value = bar[key];
}
Richard Dalton
  • 35,513
  • 6
  • 73
  • 91
1

Below is an example that gets as close as you get.

for(var key in data){
  var value = data[key];    
  //your processing here
}

If you're using jQuery see: http://api.jquery.com/jQuery.each/

Aidamina
  • 1,894
  • 20
  • 14
0

why not simply this

var donuts = [
{ type: "Jelly", cost: 1.22 },
{ type: "Chocolate", cost: 2.45 },
{ type: "Cider", cost: 1.59 },
{ type: "Boston Cream", cost: 5.99 }];

donuts.forEach(v => {console.log(v["type"]+ " donuts cost $"+v["cost"]+" each")});
gros chat
  • 11
  • 2
  • 3
    Why not include an educational explanation? The OP is wanting to grab the key and value from a 1-dimensional structure -- your answer is ignoring this requirement. – mickmackusa Jun 10 '21 at 06:32
0

Please try the below code:

<script> 
 const games = {
  "Fifa": "232",
  "Minecraft": "476",
  "Call of Duty": "182"
 };

Object.keys(games).forEach((item, index, array) => {
  var msg = item+' '+games[item];
  console.log(msg);
});
Nazmul Haque
  • 720
  • 8
  • 13
  • Why is `array` there if you aren't using it? How is your answer valuable versus the same advice from 5 years earlier? – mickmackusa Jun 10 '21 at 06:35
-2

yes, you can have associative arrays also in 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 ...
}
Alex Pacurar
  • 5,801
  • 4
  • 26
  • 33
  • @PaulPRO ... everything in javascript is a key-value pair (thus, an object is in fact an associative array of key-value pairs...) – Alex Pacurar Aug 30 '11 at 10:59
  • 1
    @AlexPacurar and assocative array has an order. An object is unordered. _thats_ a big difference – Raynos Aug 30 '11 at 13:40
  • @Raynos you may be right... it will be a great help to explain exactly how an object is unordered... given the above example, one would expect that the 'i' in the for loop to be [name, otherProperty, and finally date]... so in which situation the order of properties of an object will be mixed ? – Alex Pacurar Aug 30 '11 at 14:14
  • @AlexPacurar the particular order in which it will loop over the object is browser specific. Some do it alphabetically, some do it order of definition, etc – Raynos Aug 30 '11 at 14:58
  • 3
    @Raynos: Are associative arrays necessarily ordered? I've often seen the term used more generally. For example, on [the Associative array Wikipedia article](http://en.wikipedia.org/wiki/Associative_array). – Jeremy Aug 30 '11 at 15:20
-9
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;
user278064
  • 9,982
  • 1
  • 33
  • 46