_.each fumbles when object has a length property #659

Closed
rajeshsegu opened this Issue Jun 28, 2012 · 2 comments

Projects

None yet

4 participants

@rajeshsegu

For example, consider this server response:

response : {
length: 100;
resultsA: [a, b, c, d],
resultsB: [x, y, z]
......
}

_.each(response, function(key, value){
if(key == "length") return;
//otherwise, process results
});

This would fail to do forEach as length attribute would not let _.each to iterate as an Object iterator. In addition, there are 100 void iterations that happen before its returned.

I understand its is a bad practice to have length attribute as part of an Object but I assume underscore framework is designed to be prepared for the worst case scenario too.

Fix:

var each = _.each = .forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) { //additional check to check if obj is an array. typeof ?
for (var i = 0, l = obj.length; i < l; i++) {
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (
.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};

@michaelficarra
Collaborator

Please search next time. See #448, #297, #252, #148.

@jashkenas jashkenas closed this Jun 28, 2012
@jdalton
jdalton commented Jun 28, 2012

I've handled this in libs I use by providing something like forOwn and forIn methods. That way it gives devs a bit more control over object iteration and avoids problems with overloading forEach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment