Re: typeof document.all

On Oct 12, 2009, at 11:45 AM, Brendan Eich wrote:

> On Tue, 14 Jul 2009 07:22:24 +0000 (UTC), Ian Hickson wrote:
> > On Mon, 13 Jul 2009, Boris Zbarsky wrote:
> > >
> > > In Gecko, document.all is in fact on the prototype of the  
> document.
> > > More precisely, trying to use document.all (as opposed to just  
> test for
> > > it) changes the prototype chain of the document such that its  
> prototype
> > > has the "all" property.  Try this in your favorite Gecko-based  
> browser:
> > >
> > > <script>
> > >   var oldProto = document.__proto__;
> > >   alert(oldProto.hasOwnProperty("all"));
> > >   document.all.length;
> > >   alert(oldProto.hasOwnProperty("all"));
> > >   alert(document.__proto__.hasOwnProperty("all"));
> > >   alert(document.__proto__ == oldProto);
> > >   alert(document.__proto__.__proto__ == oldProto);
> > > </script>
> > >
> > > You should be seeing alerts with the following values: false,  
> false,
> > > true, false, true
> >
> > The "adding 'all' after it's used" behaviour doesn't match other  
> browsers
> > as far as I can tell.
>
> The prototype chain is not directly observable according to the ES  
> specs, even
> with ES5's Object.getPrototypeOf (host objects can lie).
>
> Reifying a property on first use is a common technique, an  
> optimization (not
> observable, so conforming).

In this case it's observable - the code cite above observes it. I'm  
not sure it matters in practice, but it is observable.

> For document.all, the interoperation problem (if it
> is a problem) is that Mozilla reifies depending on context. WebKit  
> reifies
> (eagerly or lazily, doensn't matter) independent of context, and  
> with a falsy
> object value.
>
> Confusion arises because undefined is a falsy value, which compares  
> == itself
> and null as well as converts to false in boolean contexts. But a  
> property that
> has value undefined is observably different from no property, even  
> if one goes
> only by the ES specs.

Specifically, the in operator and the hasOwnProperty() method will  
give different results. I think using the object in a with() statement  
will also give different results.

>
>
> > > I have no idea what the spec is saying about this, exactly (link
> > > appreciated), but document.hasOwnProperty("all") is false in  
> Gecko, and
> > > will continue to be so, I suspect; that's just not an own  
> property of
> > > that object.  The behavior is quite self-consistent, contrary to  
> Thomas'
> > > claim above.
>
> (Thomas seems to have been misled by the 'prototype' property of  
> functions and
> built-in constructors: document.prototype is an undefined property,  
> of course;
> some JS implementations support document.__proto__ as bz showed.)
>
> > http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete-features.html#dom-document-all
> >
> > See also the IDL block above it (which defines the prototype) and  
> the
> > definition of HTMLAllCollection linked to from that section that  
> defines
> > the variant of HTMLCollection used for this API (and for  
> col.tags()).
>
> If the prototype chain is not observable (by the book) why do the IDL
> definitions matter?

Web IDL defines which aspects of an IDL interface are prototype  
properties and which are own properties. The prototype chain is  
observable with nonstandard extensions, but also in part via prototype  
properties present on DOM (pseudo-)constructors.

>
> The issue is falsy object value. Must this be normative?

Some way of making document.all undetectable should be normative. We  
can discuss the pros and cons of the Gecko and WebKit solutions to  
this. It might also be possible to specify things in a way that both  
the Gecko and WebKit behaviors end up conforming, for example by  
listing a series of if tests that must pass or fail, thus leaving some  
edge cases unspecified.

Regards,
Maciej

Received on Monday, 12 October 2009 19:22:36 UTC