odoe

Stop using dojo/_base/array

Blog Post created by odoe on Dec 24, 2014

stop_array.jpg

A long time ago, when web browsers were powered by gremlins and gnomes, we used to have to use JavaScript frameworks for the simplest of tasks. The most essential methods of objects such as the Array were in their infancy.

You used to have to write loops manually, such as this:

 

for (var i = 0; i < myArray.length; i++) {
  // do something
}

 

The horror. Then JavaScript developers were give a gift. The gift of iteration methods, such as map, filter, some and more. This greatly simplified how we could write code... unless you had to support Internet Explorer 8 and below. But before there was even an Internet Explorer 8, libraries like Dojo provided utilities to mimic these functions before they were finalized. This is where dojo/_base/array provided magical methods when we had to support browsers like Internet Explorer 6. Times were looking brighter.

 

That was a long time ago. Browsers have come a long way. In my experience, even in government infrastructures, Internet Explorer 9 has become the minimum requirement I need to worry about. Dojo 2.0 is on the horizon (somewhere) and even in their own docs for dojo/_base/array it is stated:

In Dojo 2.0, this module will likely be replaced with a shim to support functions on legacy browsers that don’t have these native capabilities.

Emphasis is my own. What does that mean? That means you should stop using dojo/_base/array. That's how I'm reading it and I'm sticking to it. Do you still need to support Internet Explorer 8 and below? Use a shim/polyfill. Start writing your iterations like this:

// get the attributes of all features
var onlyAttributes = features.map(function(feature) {
  return f.attributes;
});

// find features with acreage greater than 500
var myFeatures = features.filter(function(feature) {
  return feature.attributes.ACRES > 500;
});

// add graphics to the map
features.forEach(function(feature) {
  this.map.graphics.add(feature);
}.bind(this)); // bind() is how you can pass context to functions

// find features with greater than 500 acres and get only the attributes
var myAttributes = features.filter(function(feature) {
  return feature.attributes.ACRES > 500;
}).map(function(feature) {
  return feature.attributes;
});

// get the first result of an address search
var address = addressCandidates.map(function(result) {
  return result.address;
}).shift();

 

We should be incredibly grateful for dojo/_base/array and what it brought us as JavaScript developers in our time of need. But I'm pretty confident that time is behind us.

 

When should I use dojo/_base/array?

Ok, so there is a case when dojo/_base/array would be the only way to iterate an array, actually array-like objects, like arguments.

For example:

var func1 = function() {
  arrayUtils.forEach(arguments, function(arg) {
    console.debug(arg);  
  });
};

func1(1,2,3,4); //-> 1,2,3,4

var func2 = function() {
 arguments.forEach(function(arg) {
    console.debug(arg);  
  });
};

func2(1,2,3,4); //-> throws error

 

This happens because although arguments is an array-like object that contains the arguments passed to a function, it doesn't have all the sugar a true Array has. But let's be honest here, were you really doing this? Probably not. It's typically best to avoid this behavior if you can. But if you really needed to, there is an easy way to do this.

var func3 = function() {
  [].forEach.call(arguments, function(arg) {
    console.debug(arg);
  });
};

 

Magic!

 

To summarize:

  1. Use a polyfill if you want to play it safe.
  2. Use native Array iteration methods

Outcomes