Re: indexed properties on NodeLists and HTMLCollections

Hi Allen.

Regarding the “Proxies can’t return non-configurable properties”
requirement (which I see you’ve raised on es-discuss now):

Allen Wirfs-Brock:
> Where is this requirement? Is it something in the Proxy proposal? or
> are you inferring something from the ES5 section 8.6.2 host object
> restrictions?

Yes, in the Proxy proposal, which is consistent with the host object

> > For example:
> > 
> >  var list = document.documentElement.childNodes;
> >  // list is a NodeList that happens to be implemented by a Proxy
> >  Object.defineOwnProperty(list, "a", { configurable: false, value: 1 });
> >  alert(Object.getOwnPropertyDescriptor(list, "a").configurable);
> > 
> > would that alert true?  If so, is that seen as a problem?
> I would expect it to alert true. "a" isn't a property name that is
> "live" as the one of the items of a NodeList. Hence, it should just
> have normal [[Put]]/[[Get]]//DefineOwnProperty]] behavior.

So, I tried to define a property that wasn’t configurable.  When I look
up that property, it is configurable.  That’s not normal
[[DefineOwnProperty]] behaviour. :-)

This was my concern here, that since Proxies are disallowed from
exposing non-configurable properties, it means any object in the DOM
that goes beyond native ES semantics, and happens to be implemented with
Proxies, cannot have non-configurable properties on it.

The only non-configurable properties currently required by Web IDL are
those for constants, and they live on prototype objects that don’t have
special behaviour, so there’s no problem with a native ES DOM
implementation having them be non-configurable.  So the issue is just
with user-defined own properties on these fancy objects.

> The host object restrictions on [[GetOwnProperty]] in 8.6.2 are
> these to ensure that a JS programmer always has access to reliable
> information about the mutability (and hence cache-ability) of objects
> (including host objects) and their properties. If you can't guarantee
> that a property value that is "readonly" will never change or you
> can't prevent a property from being added to a non-extensible object
> then you must disallow attempts to set the object/property attributes
> to those states. You could silently ignore the attempt but it is
> probably preferable to thrown an exception.

I don’t have a problem requiring it to be impossible to define non-
configurable own properties on NodeLists if that’s what we need to do.
(But I suspect adhering to this rule won’t fly for objects with non-
[OverrideBuiltins] named properties.)

The Safari/Chrome proposal for exposing a NodeList’s indexed properties,
including the above requirement, is something like the following:

* [[DefineOwnProperty]] does:
    * If configurable = false, throw.
    * If the property name is one of a current indexed property, do
      If the property name is an array index property at all, do
      ( OR
       An alternative is to allow the property redefinition but to
       record that the property has lost its specialness.)
    * Otherwise, do the normal [[DefineOwnProperty]] behaviour.
* [[GetOwnProperty]] does:
    * If the property name is a current indexed property, then return
      a {configurable:false,enumerable:true,get:fn} where fn returns the
      relevant Node.
    * Otherwise, do the normal [[GetOwnProperty]] behaviour of looking
      at the object for a property and returning its descriptor.

As I still think this is the simplest for authors and implementors, I’d
like to know if this is acceptable, and what people think of the options
there in [[DefineOwnProperty]].

The above ignores fixed objects.  What to do when freeze/seal/
preventExtensions is called is another question, and one I haven’t
tested current UA behaviour for.  If it’s compatible, we might like to
allow converting a live NodeList into a dead one with freeze.  (seal and
preventExtensions would be trickier to have useful behaviours for.)

Cameron McCormack ≝

Received on Sunday, 8 May 2011 22:29:03 UTC