Looping Objects is easy. Looping Arrays is also easy. Looping NodeLists is easy. They can be a little repetitive though and often take time to construct each loop and pass in the index, property, element or whatever…
There is no “standard” way of iterating over everything. We can use Array.prototype.forEach
to loop over Arrays (or the regular for
loop), a for in
loop for Objects, and a regular for
loop again for NodeLists or HTML collections. No, you’re not going to use that forEach.call(NodeList)
hack.
Table of contents
Wouldn’t it be nice to just forget about what type of collection we’re looping, forget about browser support and write a nice little function that handles everything for us. Yes.
So I did…
forEach.js
forEach.js
is a simple script, it’s not part of a library or even a module, it’s just a function, here’s its syntax and a quick example using an Array
:
// syntax
forEach(collection[, callback[, context]]);
// example
var myArray = ['A', 'B', 'C', 'D'];
forEach(myArray, function (value, index) {
// `this` will reference myArray: []
}, myArray); // note third param changing execution context
Free eBook
Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.
- Observables and Async Pipe
- Identity Checking and Performance
- Web Components <ng-template> syntax
- <ng-container> and Observable Composition
- Advanced Rendering Patterns
- Setters and Getters for Styles and Class Bindings
forEach() for Arrays/NodeLists
You can loop over an Array or NodeList using a standard for
loop, however, NodeLists cannot be used in conjunction with the newer ECMAScript 5 Array.prototype.forEach
. This script takes care of that in the same way it loops over an Array
, you’ll get the same stuff passed back:
// Array:
forEach(['A', 'B', 'C', 'D'], function (value, index) {
console.log(index); // 0, 1, 2, 3
console.log(value); // A, B, C, D
});
// NodeList:
forEach(document.querySelectorAll('div'), function (value, index) {
console.log(index); // 0, 1, 2, 3
console.log(value); // <div>, <div>, <div>...
});
forEach() for Objects
Object iteration is usually done via a for in
loop, we can wrap this up by passing back values which makes our loops cleaner and easier to manage:
// Object:
forEach({ name: 'Todd', location: 'UK' }, function (value, prop, obj) {
console.log(value); // Todd, UK
console.log(prop); // name, location
console.log(obj); // { name: 'Todd', location: 'UK' }, { name: 'Todd', location: 'UK' }
});
collection
Type: Array|Object|NodeList
Collection of items to iterate, could be an Array
, Object
or NodeList
.
callback
Type: Function
Callback function for each iteration.
context
Type: Array|Object|NodeList
Default: null
Object/NodeList/Array that forEach
is iterating over, to use as the this
value when executing callback.
Code
For those interested, check out the code below, the latest version is available on GitHub.
var forEach = function (collection, callback, scope) {
if (Object.prototype.toString.call(collection) === '[object Object]') {
for (var prop in collection) {
if (Object.prototype.hasOwnProperty.call(collection, prop)) {
callback.call(scope, collection[prop], prop, collection);
}
}
} else {
for (var i = 0; i < collection.length; i++) {
callback.call(scope, collection[i], i, collection);
}
}
};
Thank you for reading!