ChatGPT解决这个技术问题 Extra ChatGPT

For..In loops in JavaScript - key value pairs

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?


M
Michael Levy
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.)


Another way to iterate only over "own" properties is Object.keys. Object.keys(target).forEach(function (key) { target[key]; });.
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)
why not to use variables given in question example? What here is k, target and property? For me, non-javascripter this area of undefined :)
Object.keys(target).forEach((key) => { target[key]; }); for Angular
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.
M
Muhammad Dyas Yaskur

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).

Object.entries documentation

for...of documentation

Destructuring assignment documentation

Enumerability and ownership of properties documentation


This works perfect, just wondering - compared to "for key in object and then get value by object[key]", which one gives better performance?
In this specific case I would assume it's slower because of the Object.entries call. I didn't run any tests though.
this is the best answer to the question at hand, which asked about grabbing both key and value in the for loop.
The accepted answer should be updated since this actually answers the question, although it wasn't available at time of the question.
You might want to check this question: stackoverflow.com/questions/47213651/… which seems to indicate that a syntax of this type would be recommended: Object.keys(myObject).forEach(key => {...
A
Afshin Moazami

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

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

Note: Not supported by IE8 and below.
At this point you should be using an ES5 shim. If you're living in the nice ES6 future use for of tc39wiki.calculist.org/es6/for-of
It is worth noting, that "There is no way to stop or break a forEach() loop other than by throwing an exception"
Object.keys(obj).forEach((key) => { }); for Angular
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... });
P
Paul

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 ) ) {

}

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

}

The php syntax is just sugar.


This will also iterate on all inherited properties. To avoid this, use .hasOwnProperty().
F
Felix Kling

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.


That's Array forEach, not object forEach.
So? Apparently the OP is looping over an array.
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: Right, but as it is Mozilla only, it does not seem to be very useful.
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.
C
Christoph Winkler

You can use the for..in for that.

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

S
Siddhu
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.


T
Tonatio

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

Select values: Object.values(obj).forEach(value => ...); Select keys: Object.keys(obj).forEach(key => ...); Select keys and values: Object.entries(obj).forEach(([key, value]) => ...);


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

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

You may add some explanation with the code you posted instead of posting a plain code which might be not understandable.
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.
D
David

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}`);
}

S
Stephen Murby

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

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

what's the parameter myMap for?
A map is not an object. They are completely separate things.
The forEach function does not contain the 'key' of the array but more the index of the element that you are currently iterating.
R
Richard Dalton

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

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

A
Aidamina

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/


G
Gil Epshtain

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).

g
gros chat

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")});

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.
N
Nazmul Haque

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);
});

Why is array there if you aren't using it? How is your answer valuable versus the same advice from 5 years earlier?
A
Alex Pacurar

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 ...
}

@PaulPRO ... everything in javascript is a key-value pair (thus, an object is in fact an associative array of key-value pairs...)
@AlexPacurar and assocative array has an order. An object is unordered. thats a big difference
@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 ?
@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: Are associative arrays necessarily ordered? I've often seen the term used more generally. For example, on the Associative array Wikipedia article.
u
user278064
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;