The callback for Array.prototype.forEach is given three arguments, the current value, the index, and the array itself. val is the second argument (which should really be given a more appropriate name), so it is the index, which is a number.
This may help you understand:
let obj = {a: '1', b: '2'};
Object.keys(obj).forEach(function(key, idx, arr){
console.log("Key:", key);
console.log("Index:", idx);
console.log("Original Array:", arr);
console.log("Value:", obj[key]);
});
Alternatively, you can use Object.entries to directly access values (with destructuring):
let obj = {a: '1', b: '2'};
Object.entries(obj).forEach(function([key, val], idx, arr){
console.log("Key:", key);
console.log("Index:", idx);
console.log("Original Array:", arr);
console.log("Value:", val);
});
Answer from Unmitigated on Stack OverflowThe callback for Array.prototype.forEach is given three arguments, the current value, the index, and the array itself. val is the second argument (which should really be given a more appropriate name), so it is the index, which is a number.
This may help you understand:
let obj = {a: '1', b: '2'};
Object.keys(obj).forEach(function(key, idx, arr){
console.log("Key:", key);
console.log("Index:", idx);
console.log("Original Array:", arr);
console.log("Value:", obj[key]);
});
Alternatively, you can use Object.entries to directly access values (with destructuring):
let obj = {a: '1', b: '2'};
Object.entries(obj).forEach(function([key, val], idx, arr){
console.log("Key:", key);
console.log("Index:", idx);
console.log("Original Array:", arr);
console.log("Value:", val);
});
val is just a foreach iterator index number. You need to use obj[key] to get the value
Is Object.keys(obj).forEach really any better than for-in loop?
For...in vs Object.keys
How to loop through a plain JavaScript object with the objects as members - Stack Overflow
Iterate over object keys in node.js - javascript
Videos
In Douglas Crockford's talk at Nordicjs in 2014 he says that he now prefers this syntax over for-in:
Object.keys(obj).forEach(function(key) { /* ... */ });However jsperf says it's slower and every performance metric I can find says it's slower. Did I miss anything here? I wonder why Crockford prefers it...
Hey all, this is solely for for my own curiosity, but what would be preferred in any given situation while iterating over an object, "for...in", or "Object.keys(obj).forEach()"?
I generally favor "for...in", but it occurred to me the .forEach() method may work just as well.
Example:
var obj = { prop1 : "some val", prop2 : "some other val"};
for(key in obj){
console.log("Key: ", key)
console.log("Value: ", obj[key])
}
Object.keys(obj).forEach((key)=>{
console.log("For Each Key: ", key)
console.log("For Each Value: ", obj[key)
})
for (var key in validation_messages) {
// skip loop if the property is from prototype
if (!validation_messages.hasOwnProperty(key)) continue;
var obj = validation_messages[key];
for (var prop in obj) {
// skip loop if the property is from prototype
if (!obj.hasOwnProperty(prop)) continue;
// your code
alert(prop + " = " + obj[prop]);
}
}
Under ECMAScript 5, you can combine Object.keys() and Array.prototype.forEach():
var obj = {
first: "John",
last: "Doe"
};
//
// Visit non-inherited enumerable keys
//
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
What you want is lazy iteration over an object or array. This is not possible in ES5 (thus not possible in node.js). We will get this eventually.
The only solution is finding a node module that extends V8 to implement iterators (and probably generators). I couldn't find any implementation. You can look at the spidermonkey source code and try writing it in C++ as a V8 extension.
You could try the following, however it will also load all the keys into memory
Object.keys(o).forEach(function(key) {
var val = o[key];
logic();
});
However since Object.keys is a native method it may allow for better optimisation.
Benchmark
As you can see Object.keys is significantly faster. Whether the actual memory storage is more optimum is a different matter.
var async = {};
async.forEach = function(o, cb) {
var counter = 0,
keys = Object.keys(o),
len = keys.length;
var next = function() {
if (counter < len) cb(o[keys[counter++]], next);
};
next();
};
async.forEach(obj, function(val, next) {
// do things
setTimeout(next, 100);
});
Also remember that you can pass a second argument to the .forEach() function specifying the object to use as the this keyword.
// myOjbect is the object you want to iterate.
// Notice the second argument (secondArg) we passed to .forEach.
Object.keys(myObject).forEach(function(element, key, _array) {
// element is the name of the key.
// key is just a numerical value for the array
// _array is the array of all the keys
// this keyword = secondArg
this.foo;
this.bar();
}, secondArg);