I read on Javascript: The Good Parts...
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...
As far as I know the "each" functions are based in for in
, then does each
function form JQuery and Underscore libraries guarantee order when they iterate over an Array? I'm trying to avoid the annoying standard for
.
Thank you in advance.
When iterating through an array, order is always guaranteed. It's when you iterate through (non-array) objects is when there's no guarantee. Arrays are still objects by the way.
each
is no more than a for in
for objects, and for
for array-like. the framework determines the right loop for the job and the same logic applies: Arrays iterations are orderly while object iteration isn't.
Underscore's source:
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 (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
jQuery's source:
each: function (object, callback, args) {
var name, i = 0,
length = object.length,
isObj = length === undefined || jQuery.isFunction(object);
if (args) {
if (isObj) {
for (name in object) {
if (callback.apply(object[name], args) === false) {
break;
}
}
} else {
for (; i < length;) {
if (callback.apply(object[i++], args) === false) {
break;
}
}
}
// A special, fast, case for the most common use of each
} else {
if (isObj) {
for (name in object) {
if (callback.call(object[name], name, object[name]) === false) {
break;
}
}
} else {
for (; i < length;) {
if (callback.call(object[i], i, object[i++]) === false) {
break;
}
}
}
}
return object;
}