4

In lodash you can find the following functions:

_.forOwn _.forOwnRight

Example for forOwn function iterates properties in a-z order, but says:

iteration order is not guaranteed

While forOwnRight claims to be iterating in opposite (z-a) order.

This does not make much sense to me, so there are 2 questions

  1. Why does forOwnRight even exist if there is no guarantee on iteration order?
  2. Why can't the order be guaranteed?
Anri
  • 5,947
  • 3
  • 33
  • 59

3 Answers3

6
  1. The order is not guaranteed but is consistent. It means that _.forOwnRight is guaranteed to provide the result reversed from _.forOwn

  2. It's as per specification: it does not state how object's properties must be ordered so it's up to JS engine how to handle it (and they do that differently for performance reasons).

A note: the order depends not only on the particular ES implementation, but also on runtime, since modern JS VMs do a lot of heuristics in runtime.

For the ones curious about optimizations here is a good link (it seriously does not fit to cover in this Q/A):

zerkms
  • 230,357
  • 57
  • 408
  • 498
1

Looking at the source we can see that:

function baseForOwn(object, iteratee) {
    return baseFor(object, iteratee, keys);
}

function baseForOwnRight(object, iteratee) {
    return baseForRight(object, iteratee, keys);
}

function baseFor(object, iteratee, keysFunc) {
    var index = -1,
        iterable = toObject(object),
        props = keysFunc(object),
        length = props.length;
    while (++index < length) {
        var key = props[index];
        if (iteratee(iterable[key], key, iterable) === false) {
            break;
        }
    }
    return object;
}

function baseForRight(object, iteratee, keysFunc) {
    var iterable = toObject(object),
        props = keysFunc(object),
        length = props.length;
    while (length--) {
        var key = props[length];
        if (iteratee(iterable[key], key, iterable) === false) {
            break;
        }
    }
    return object;
}

Both of the functions internally rely on keysFunc, which returns the keys of the passed object. Since the order of an object's keys is not strictly defined the order cannot be known beforehand, however both of the methods internally use the same method, so the reversed order is guaranteed to be an exact reversal.

Etheryte
  • 20,940
  • 10
  • 58
  • 98
1

I think it is easier to answer question 2 first.

  1. Both functions forOwn and forOwnRight works with objects, therefore, the order of the properties is not guaranteed, as stated in 4.3.3 Objects of the Ecma-262 specification :

[An object] is an unordered collection of properties each of which contains a primitive value, object, or function.

Usually the properties are printed by VMs in their insertion order, but that should not be taken as a general fact. Refer also to this question for more details.

  1. Though, assuming forOwn processes the properties in the following order [a, c, b] on a particular javascript runtime, you have a guarantee that forOwnRight will process the properties in the order [b, c, a]. Therefore there is sense to have both methods.
Community
  • 1
  • 1
Michael P. Bazos
  • 21,340
  • 5
  • 58
  • 60