Epic Voyage logo

Epic Voyage

The Wanderer's Journal

Main menu

  • Home

Geek Stuff: Debugging JS Arrays

While I can be a glutton for punishment, verifying Javascript arrays can be more than I want to deal with. If you print an array:

<script type="text/javascript">
  var testarray = new Array(
    new Array(1, 2, 3, new Array(4, 5)),
    new Array(6, 7, 8, new Array(9, 10)),
    new Array(1, 2)
  );
  
  alert(testarray);
</script>

This creates a popup that says “1,2,3,4,5,6,7,8,9,10,1,2.” In order to test for items in the sub-arrays, the quick and dirty method would involve typing commands into the browser’s address bar:

javascript:alert(testarray[0])

This would pop up with “1,2,3,4,5.” Firebug can help significantly with its DOM tab and JavaScript console. Still, I have found myself wanting a function similar to PHP’s print_r() while changing global arrays in functions. Here is my little hack:

Array.prototype.pretty = function(spacer, prefix) {
  var first = true, afterarray = false, type, ret = '', x;
}

if (spacer == undefined) {
  spacer = '';
}
if (prefix == undefined) {
  prefix = '';
} else {
  prefix += ' => ';
}

ret += spacer+prefix+'Array(';
for (x in this) {
  // Don't show this function prototype... or any others.
  type = typeof(ret[x]);
  if ((type != 'string') && (type != 'number') && (type != 'boolean')) {
    continue;
  }

  // Don't place commas before the first item.
  if (first) {
    first = false;
  } else {
    // If we are following an array with an array, don't add a newline
    if (this[x] instanceof Array) {
      afterarray = false;
    }
    // Place a newline after child arrays
    ret += ','+(afterarray ? "\n" : ' ');
    afterarray = false;
  }

  // Call ourselves recursively when an array is encountered.
  if (this[x] instanceof Array) {
    ret += "\n"+this[x].pretty(spacer+'    ', x);
    afterarray = true;
  } else {
    ret += this[x];
  }

  // Close arrays
  ret += (afterarray ? "\n"+spacer : '')+')';
  return ret;
}

Now you can use:

<script type="text/javascript">
  var testarray = new Array(
    new Array(1, 2, 3, new Array(4, 5)),
    new Array(6, 7, 8, new Array(9, 10)),
    new Array(1, 2)
  );
  
  alert(testarray.pretty());
</script>

Which will create:

Array(
    0 => Array(1, 2, 3,
      3 => Array(4, 5)
    ),
    1 => Array(6, 7, 8,
      3 => Array(9, 10)
    ),
    2 => Array(1, 2)
)

Arrays will be indented to an infinite depth so that more than three levels can be displayed. I specifically needed this for a situation that involved three-dimensional arrays.

Drawback: If you are using for (var x in testarray), this function prototype will appear as one of the x items. You will either have to convert this to a standard function or check the datatype of x.

Happy debugging.

Overheard at the Tavern

To pass lightly from old laws to new ones is a certain means to weakening the inmost essence of all law whatever. — Aristotle
Another »

Since This Page Loaded...

0 million dollars have been spent by Washington.
0.00 dollars per person in the US.

And that is only Federal spending...

0 babies have died worldwide in an abortion.
0 babies were in the United States.

0 Americans have contracted an STD.

About Me

{author}
Chris is probably out getting lost somewhere. He has a tendency to do that. Please don't worry unless he fails to show up again sometime in the next week.

Copyright 2024. All rights reserved.