Lastly I was skimming through Underscore.js code to learn JavaScript idioms and I found following definition of each function:
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) {
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 (hasOwnProperty.call(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
What this line is for? (I assume that this is a way of checking if passed object is an array, am I right? If so, wouldn’t be an typeof operator better approach?)
obj.length === +obj.length
The
eachmethod accepts Collections (Arrays or Objects).After checking if the native method forEach is available, the method checks if
objis an Array. This is not possible usingtypeofsince typeof will return"object"for arrays as well for objects (trytypeof [] === typeof {}). So, they used theobj.length === +obj.lengthapproach.This works because if
objdoesn’t have thelengthproperty,+obj.lengthreturnsNaNand the strict comparison fails. Then, the method assumesobjis anobject.