Take the 2-minute tour ×

I've started working with Qunit to do unit testing on my code, but am striking problems comparing objects.

The code I'm testing dynamically creates an object:

var fields = ['id','name'];
var result = {};
for (var field in fields)
    var name = fields[field];
    result[name] = name;

var expected = { id : 'id', name : 'name' };

test(expected, result, "same ?");

This test fails, and I can see that while expected just contains the fields id and name, result also contains a whole lot of functions, eg

"function (iterator, context) {...

I think these functions come from me treating the object like an array in order to assign to it.

Is there a way to strip these functions out (or prevent them from getting added in the first place)?

I was thinking of doing

result = $.parseJSON($.toJSON(result));

is there a better way?

share|improve this question
I forgot to mention I'm using jquery and prototype libraries, not sure if these are the cause of the additional object properties. –  Chris J Dec 17 '10 at 3:48
It doesn't have anything to do with jQuery or Prototype. JavaScript's native for in construct will unearth every single object property, including inherited ones. For arrays, always use the conventional for loop if you're only after the array elements. –  Rob Sobers Dec 17 '10 at 4:06
add comment

3 Answers

up vote 3 down vote accepted

You can check the type of each object in the collection to see if it's a function:

if(typeof fields[field] == 'function') continue;

Also, don't use for..in on arrays:

   result[result[i]] = result[i];

What you have there isn't strictly an object, it's an Array object, which is nevertheless an object, but not in the sense that it has key-value pairs.

If you use a vanilla for loop, you will not iterate through the prototype chain as you do with for..in, so maybe doing that might solve your problem.

share|improve this answer
I'd prefer not to rewrite qunit's equals function if possible. Then the only other way to use that would be to iterate over, and delete result[name] if it's a function, but I thought there would be a cleaner way to do it. –  Chris J Dec 17 '10 at 3:47
Ah, i see, looking at the wrong for loop. Cheers. –  Chris J Dec 17 '10 at 7:05
There is always hasOwnProperty() (not that I condone its use) :) –  alex Dec 19 '10 at 1:59
add comment

The problem is your use of for...in, which is iterating over everything fields is inheriting from object. If you must keep for...in, you can modify it like this:

for (var field in fields){
  if( fields.hasOwnProperty( field ) ){
    var name = fields[field];
    result[name] = name;

hasOwnProperty returns true if the specified property of the object (and the array is an object) is not inherited.

share|improve this answer
+1 for hasOwnProperty() –  alex Dec 19 '10 at 4:20
add comment

You shouldn't use for in on Arrays. Chapter 6 of JavaScript: The Good Parts provides a great explanation:

Since JavaScript's arrays are really objects, the for in statement can be used to iterate over all of the properties of an array. Unfortunately, for in makes no guarantee about the order of the properties, and most array applications expect the elements to be produced in numerical order. Also, there is still the problem with unexpected properties being dredged up from the prototype chain.

Use the conventional C-style for loop instead.

share|improve this answer
add comment

Your Answer


