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
- Why does
forOwnRight
even exist if there is no guarantee on iteration order? - Why can't the order be guaranteed?
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
- Why does
forOwnRight
even exist if there is no guarantee on iteration order? - Why can't the order be guaranteed?
3 Answers
Reset to default 6The order is not guaranteed but is consistent. It means that
_.forOwnRight
is guaranteed to provide the result reversed from_.forOwn
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):
- https://developers.google./v8/design
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.
I think it is easier to answer question 2 first.
- Both functions
forOwn
andforOwnRight
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.
- Though, assuming
forOwn
processes the properties in the following order[a, c, b]
on a particular javascript runtime, you have a guarantee thatforOwnRight
will process the properties in the order[b, c, a]
. Therefore there is sense to have both methods.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744376386a4571206.html
评论列表(0条)