Get super confident at JavaScript. Javascript Icon

I promise to change your JavaScript skills!

Simple forEach implementation for Objects NodeLists Arrays

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.

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
Angular Directives In-Depth eBook Cover

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.

  • Green Tick Icon Observables and Async Pipe
  • Green Tick Icon Identity Checking and Performance
  • Green Tick Icon Web Components <ng-template> syntax
  • Green Tick Icon <ng-container> and Observable Composition
  • Green Tick Icon Advanced Rendering Patterns
  • Green Tick Icon 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!

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover