- From: Ojan Vafai <ojan@chromium.org>
- Date: Tue, 3 Jan 2012 18:18:45 -0800
- To: Cameron McCormack <cam@mcc.id.au>
- Cc: "public-script-coord@w3.org" <public-script-coord@w3.org>, Boris Zbarsky <bzbarsky@mit.edu>, Travis Leithead <Travis.Leithead@microsoft.com>, Allen Wirfs-Brock <allen@wirfs-brock.com>, Ian Hickson <ian@hixie.ch>
- Message-ID: <CANMdWTvMkUXez=miUeRCeP36yO+JpAea9o0=MFZ8djFPMnN1Mg@mail.gmail.com>
On Tue, Jan 3, 2012 at 4:51 PM, Cameron McCormack <cam@mcc.id.au> wrote: > In https://www.w3.org/Bugs/**Public/show_bug.cgi?id=8241<https://www.w3.org/Bugs/Public/show_bug.cgi?id=8241>we finally settled on the name resolution order for the window object to be > the following: > > 1. Own properties on window (which would include JS builtin > global properties like Array, Object, etc.) and global variables > 2. Properties from the prototype chain (which would include > "constructor" & event listener properties) > 3. Frames > 4. Global scope polluter > > Since the Window interface is also declared with > [ReplaceableNamedProperties], allowing assignments to window object > properties to shadow named properties, the following document should alert > "[object Window]" and then "a": > > <!DOCTYPE html> > <iframe name=x></iframe> > <script> > alert(x); > x = "a"; > alert(x); > </script> > > The question I have (which Ojan raised in the content of > http://code.google.com/p/**chromium/issues/detail?id=**80591<http://code.google.com/p/chromium/issues/detail?id=80591>) > is what the following document should alert: > > <!DOCTYPE html> > <iframe name=x></iframe> > <script> > alert(x); > </script> > <script> > var x; > alert(x); > </script> > > I had thought that current specs would cause this to alert "[object > Window]" and then "undefined" (which I think is preferable to the > alternative) but now looking closer I don't think this is true. > > Here's current browser behaviour: > > Firefox nightly: "[object Window]" / "[object Window]" > Opera.next: "[object Window]" / "undefined" > Safari/WebKit nightly: "[object DOMWindow]" / "[object DOMWindow]" > Chrome nightly: "[object DOMWindow]" / "[object DOMWindow]" > IE 10pp1: "[object Window]" / "undefined" > Firefox behaves differently for frames and elements I believe (or maybe names versus IDs?). <div id="a"></div><script>alert(a);</script> // Alerts "[object HTMLDivElement]" <div id="a"></div><script>alert(a);var a;</script> // Alerts "undefined" <div id="a"></div><script>var a;alert(a);</script> // Alerts "undefined" My strong preference is that declaring a variable should cause it to shadow (i.e. alert undefined above). Not shadowing has been a frequent source of bugs for the Closure Compiler in WebKit. Shadowing makes it much easier to reason about how library code will behave when embedded in a page. All the people I've spoken to about this in the WebKit community are fine with changing WebKit once the behavior is clearly specced. I don't have strong opinions about what path to take in the spec to achieve this behavior. This is why I think currently the specs support the Firefox/Safari/Chrome > behaviour: > > * The ECMAScript spec says that the global environment (the one affected > by var statements in global code) is an object environment record > with its binding object being the global object. > > http://people.mozilla.org/~**jorendorff/es5.html#sec-10.2.3<http://people.mozilla.org/~jorendorff/es5.html#sec-10.2.3> > > * Named properties are exposed on the window object through the > [[GetOwnProperty]] definition in Web IDL. > > http://dev.w3.org/2006/webapi/**WebIDL/#getownproperty<http://dev.w3.org/2006/webapi/WebIDL/#getownproperty> > > * Since the Window interface has a getter but no setter, the descriptors > for the named properties are exposed as > { configurable: true, enumerable: true, writable: false, value: V } > > * There is no custom [[HasProperty]] defined in Web IDL, so when called > on the window object with the name of a named property it will return > true. > > * When the second <script> element in the document is run, the var > statement will be run as described in: > > http://people.mozilla.org/~**jorendorff/es5.html#sec-10.5<http://people.mozilla.org/~jorendorff/es5.html#sec-10.5> > > and in that algorithm we'll get to step 8.b, to determine whether a > variable binding for the name "a" already exists. That step calls > the HasBinding operation for object environment records: > > http://people.mozilla.org/~**jorendorff/es5.html#sec-10.2.**1.2.1<http://people.mozilla.org/~jorendorff/es5.html#sec-10.2.1.2.1> > > which returns the result of [[HasProperty]], which in this case will > be true. That'll mean step 8.c.i, which calls CreateMutableBinding, > is never run. > > > Note that if the var statement has a variable assignment, such as in > > <!DOCTYPE html> > <iframe name=a></iframe> > <script> > var a = 1; > </script> > > then the named property *will* be shadowed, due to the use of > [ReplaceableNamedProperties] on the Window interface. It's basically the > same case as just having `a = 1;` as the script, due to the var declaration > not having any effect. > > > If we want var statements without a variable assignment to shadow named > properties, then we can't keep [[GetOwnProperty]] returning property > descriptors for them while [[HasProperty]] returns true for them, without > violating the ECMAScript spec. > > We could either make [[HasProperty]] return false for named properties on > window despite [[GetOwnProperty]] returning a property descriptor. Or, we > could make the window object have a custom [[GetProperty]] instead of > [[GetOwnProperty]], so that [[HasProperty]] returns false and > [[GetOwnProperty]] returns undefined, while fetching the property off the > object still gives you the named property value. > > So two questions: > > 1. Just to confirm, is having assignment-less var statements shadow > named properties the behaviour we want? > > 2. Is either of the above alternatives for achieving it preferable, or > is there another, better way I haven't thought of? > > Thanks, > > Cameron >
Received on Wednesday, 4 January 2012 06:32:08 UTC