iteration order for Object

David Bruant bruant at enseirb-matmeca.fr
Fri Mar 11 02:39:21 PST 2011


Le 11/03/2011 00:48, Charles Kendrick a écrit :
> I believe it is very very important that the ECMAScript standard
> specify that when a new Object
> is created, for..in iteration traverses properties in the order they
> are added, regardless of whether the properties are numeric or not.
(...)
> == Expressiveness and Performance argument
>
> A very common use case where order preservation is desirable is
> providing the set of options
> for a drop-down list in JavaScript.  Essentially all Ajax widget kits
> have such an API, and
> usage is generally:
>
>    selectControl.setOptions({
>       storedValue1 : "displayValue1",
>       storedValue2 : "displayValue2",
>       storedValue3 : "displayValue3"
>    })
This is one (very valid, intuitive and common) use case. What if I want
to implement some sort of dictionnary and want keys to be ordered in
alphabetic order?
If the spec imposes one order, then people with other use cases have
additional work. Since so far, the spec has never said anything about
property ordering, it would create some biase to add to the spec one
specific order.


The problem you're pointing at is that you want ordered key->value maps
and you want this to be objects (which are already unordered key->value
maps). It appears to me that ES Objects haven't been designed to be
ordered so far.
ES5.1 - 4.2: "An ECMAScript object is a collection of properties".

To have ordered key->value maps, possible solutions are:
- Change the spec
- Add an OrderedObject as Jeff Walden suggested. This doesn't even need
to be added to the spec since proxies allow to implement them. It
however doesn't solve the JSON use case, I agree.
- Play with value proxies
(http://wiki.ecmascript.org/doku.php?id=strawman:value_proxies). Maybe
that these could allow to redefine JSON objects initialisation rules in
order to specify an order (or return an OrderedObject). I'm not a big
fan of this last idea but it could work.


I'd like to clarify the use case you're pointing. Do you have something
like:
-------------------
/* some sort of meta-JS */
selectControl.setOptions = function(keyValMap){
    foreach(key => val){ /* doesn't exist in JS. Change depending on the
keyValMap implementation */
        this.addOption(key, val); // key and val are strings
    }
}

selectControl.setOptions(objectOrOneAlternateSolution)
-------------------
The point I am trying to make is that having keys and values as strings
is required by the DOM API in order to create the option elements, so
when you mention "2 Strings per property", this is work that has to be
done anyway. This might even be cheaper to have strings created from
parsing the source than "extracted" as object property names.

Then, I am surprised when you point an issue with linear search. Why
would you want to search for properties if your use case is to use the
implicit order of object initialisation in order to make option
elements? What is your exact use case?
Regardless, I agree with the verbosity of alternative solutions.

If I understand well, you're asking for objects to be indexed by
property names and iterated by addition order. In my opinion, this is
asking a lot if we also want performance.

David


More information about the es-discuss mailing list